Generating objects dynamically using an array of paths in dot notation

Is it possible to dynamically generate an object with an array of strings in dot notation? The idea is to construct a JSON object from a CSV file, filter the properties, and create a new JSON object.

Let's say we want to pass something like this...

var obj = {};
var keyArray = ['meta', 'logos', 'warranty', 'specs', 'specs.engine', 'specs.engine.hp', 'specs.engine.rpm', 'specs.engine.manufacturer'];

The desired outcome would be...

obj = {
 meta: {
 },
 logos: {
 },
 specs: {
    engine: {
       hp: {
       }
    }
 }
}

Here is the key function

function addObjectsByKey(obj, keyArray) {

    for (var key in keyArray) {

        // Check if keyword is not in object notation
        if (!(keyArray[key].match(/\./))) {

            // If the object property is not set, set it
            if (!(obj[keyArray[key]])) {

                obj[keyArray[key]] = {};

            }

        } else {

            // Split array element (in dot notation) into an array of strings
           // These strings will be object properties
            var pathAsArray = keyArray[key].split('.');
            var path = null;

            for (var k in pathAsArray) {
                if (path == null) {
                    obj[pathAsArray[k]] = {};
                    path = pathAsArray[k];
                } else {
                    obj[path][pathAsArray[k]] = {};
                    path += '.' + pathAsArray[k];
                }
            }
            // throw Error('end');

        }

    }
    // return obj;
}

Answer №1

To create a nested object, you can utilize a forEach loop. Within the loop, split each element by . and then employ the reduce method to construct the object hierarchy.

var keyArray = ['meta', 'logos', 'warranty', 'specs', 'specs.engine', 'specs.engine.hp', 'specs.engine.rpm', 'specs.engine.manufacturer'];
const result = {}
keyArray.forEach(key => {
  key.split('.').reduce((r, e) => r[e] = (r[e] || {}), result)
})

console.log(result)

If you prefer a different approach, you can use for loops to achieve the same outcome.

var keyArray = ['meta', 'logos', 'warranty', 'specs', 'specs.engine', 'specs.engine.hp', 'specs.engine.rpm', 'specs.engine.manufacturer' ];
const result = {}

for(var i = 0; i < keyArray.length; i++) {
  const keys = keyArray[i].split('.');
  let ref = result;
  for(var j = 0; j < keys.length; j++) {
    const key = keys[j];
    if(!ref[key]) ref[key] = {}
    ref = ref[key]
  }
}

console.log(result)

Answer №2

To create a path, you can utilize the reduce function in conjunction with a nested forEach.

  • The initial reduce will accumulate the nested action.
  • Within the nested forEach, the object and its children will be constructed based on the current path delimited by dots.

let keyArray = ['meta', 'logos', 'warranty', 'specs', 'specs.engine', 'specs.engine.hp', 'specs.engine.rpm', 'specs.engine.manufacturer'],
    newObj = keyArray.reduce((accum, path) => {
      let previous = accum;
      path.split('.').forEach(key => {
        if (previous[key]) previous = previous[key];
        else previous = previous[key] = {};
      });
      
      return accum;
    }, {});

console.log(newObj);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I reset the DefaultValue of my Autocomplete input field after submitting?

Is there a way to reset the default value of my <TextField> inside Autocomplete after form submission? Even after submitting the form, the state of formValues remains as the default value. What can I do to fix this issue? I've attempted to mod ...

Activate the checkbox input by defining the form type with Javascript

I am attempting to control the enabling or disabling of input types based on whether a checkbox is checked or unchecked using JavaScript. Here is the code I am using: <script language="JavaScript"> <!-- function enable_text(status) { status=!st ...

Retrieve the nested dictionary

I have extracted a series of elements from an excel datarow: 'Ars','Cr','Assl','Burg','Consp' My goal is to organize them into a nested dictionary as shown below: data_dict.update({'name':&a ...

Is there a way to input text instead of a URL into the Smmry API?

I have a very specific question that I'm not sure anyone can answer, but I'll ask anyway. The Reddit TLDR bot uses the Smmry API to summarize content, and I'm trying to create something similar. However, the documentation only mentions passi ...

The NodeJS server experiences a crash immediately after attempting to save data into the MongoDB database

I have encountered an issue with a script that saves objects to a MongoDB database using mongoose. The object is successfully saved to the database, but immediately after, the server crashes and throws the error message: catch(err) { process.nextTick(funct ...

Ajax received a response from http 409 and is now parsing it

Hey there! I've been working on parsing out the message object using Ajax, and I'm having a bit of trouble getting a reference to messages.msg. It's strange because it displays perfectly fine in Postman, but for some reason, I can't see ...

What is the process for displaying JSON event data on FullCalendar using Zend Framework 2?

I am currently new to zf2 and I am utilizing fullcalender to display events on the calendar. To achieve this, I have created a loadaction that returns a response in the following format: [{"event_id":"2","calendar_id":"1","author_id":"1","title":"Launch", ...

The MDL layout spacer is pushing the content to the following line

Here's an interesting approach to Material Design Lite. In this example from the MDL site, notice how the 'mdl-layout-spacer' class positions elements to the right of the containing div, giving a clean layout: Check it out <!-- Event ca ...

Securing $_FILES Filenames in PHP

I have a form with an "attachments" field where users can add multiple attachments. Before uploading each attachment, I use a function to make the file name safe. Here is the function: function safeFile($file) { $lower = strtolower($file); $trim ...

What is the best way to combine two JavaScript objects?

One object I am currently working with resembles the following structure let ob1 = { 'item_data':{ 'stack':{ 'purchase':'12345', 'order':'22222' } } } Additionally, I have anothe ...

Find the object in an array that has the most recent date property

Suppose I have an array of objects like this : let sampleArray = [ { "id": 5, "date": "2016-01-15T16:18:44.258843Z", "status": "NEW", "created_at": "2016-01-29T13:30:39.315000Z", "updated_at": "2016-01-29T13:30:39.315000Z", "requ ...

How can one retrieve every element within nested associative arrays?

Situation : Upon receiving a JSON array from a jQuery <-> PHP Ajax request, the unparsed JSON array structure appears as follows: {"Focus":{"id":2,"brand":"Ford","name":"Focus"}} Upon using JSON.parse(json);, the structure transforms to: Foc ...

Optimizing Midnight UTC+0 Setting in JavaScript Date Functions

I am using an MUI Datepicker that allows me to choose a day without specifying the time. For example, if I select 01.09.1970, in the console log it displays as Tue Sep 01 1970 00:00:00 GMT+0100 (Central European Standard Time). This indicates that even tho ...

Determining the quantity of items in a MongoDB collection using Node.js

Having recently delved into Node.js and MongoDB, I find myself struggling to grasp the concept of callbacks. Despite reading several articles, the topic remains confusing to me. In the snippet of code below, my aim is to retrieve the count of orders with s ...

Guide to capturing and playing audio on iOS6 with HTML5

Our team is currently working on a web application using HTML5 and Javascript. We are facing a challenge with implementing voice recording functionality, as the Wami Api we tried is not compatible with iPad due to its use of flash for recording. Could yo ...

Typescript - Error in Parsing: Expecting an expression

I am currently working with Vue and TypeScript and have encountered a problem. How can I resolve it? Here is the code snippet in question: private setTitle(systemConfig: any) { const systemConfigParse; let obj; systemConfigParse = JSON.parse(sy ...

Adjusting the height of a textarea within a table

My textarea's height is supposed to be 500%, but it's not changing. I suspect that being inside a table might have something to do with the issue, but I'm unsure of what needs to be adjusted to set the height correctly. Surprisingly, the wid ...

[Protractor][Internet Explorer 11]-->I am facing an issue where clicking on a link does not open a new tab even though I have configured the IE browser settings properly

For example: ele.click(); is able to open a new tab in Chrome and Firefox, but not in IE11. However, if I manually click the link, it will open a new tab in IE11. Can someone explain why this is happening? What steps should I take to resolve it? Thank y ...

Unresponsive jQuery Autocomplete function failing to trigger

There seems to be an issue with the unobtrusive autocomplete feature not working on the Sales/Accounts page of my application. I have followed advice from different sources, including a blog post linked here, on how to set up the autocomplete functionality ...

Display all months vertically with Bootstrap-Year-Calendar instead of horizontally

I recently integrated the Bootstrap-Year-Calendar plug-in into my project, but it seems to be displaying vertically. I'm not sure if this issue is related to my scripts or links. I attempted to change the versions of both jQuery and Bootstrap, but the ...