简体   繁体   中英

Combine arrays into nested objects

So this is a little trippy, but here goes.

Let's say I have two arrays-- a 1D array that contains set of of categories, and a 2D array that contains an arbitrary number of arrays whose contents follow the category templates established by the first array. For instance:

var categoryArray = ["Name", "Title", "Hire Date"];
var infoArray = [["John","Project Manager","January 5"], ["Alex","Accountant","December 15"], ["Joanne","Graphic Designer","August 26"]];

What I'd like to do is consolidate this information into a single object. So up top I drop:

var myDict = {};

My (obviously wrong) attempt was to have nested for-loops which go through each array and attempts to fill the myDict object with the contents of the arrays. It looks like this:

// Start by iterating by the length of the info array, so we assign a new sub-object to the myDict Object for each entry.
for (i = 0; i < infoArray.length; i++) {
    // Each entry will be a new "row," like in a spreadsheet. 
    var row = String("row"+i);
    // I'm guessing that the declaration below doesn't actually assign the "Row1", "Row2", etc as nested objects like I had intended, but just re-writes a child called "row"
    myDict.row = {};
    // Next we iterate through the number of categories we'll need-- and we'll pull from the length of our categoryArray so we can change the number of categories later.
    for (x = 0; x < categoryArray.length; x++) {
        // In theory, the first iteration of this will create a child of "row1" called "name," which will hold a value of "John" (so, the value stored infoArray[1][1])
        myDict.row.categoryArray[x] = infoArray[i][x];
    }
}

There's clearly a LOT wrong in there, but I'm totally scratching my head about how to approach this. I guess the key problem is trying to assign the actual strings held by variables/arrays as names for objects/children, but a thorough googling has produced no answers.

Save me oh mighty internet!

var result = infoArray.map(function(currentArray) {
    return categoryArray.reduce(function(previous, currentKey, index) {
        previous[currentKey] = currentArray[index];
        return previous;
    }, {});
});

Output

[ { Name: 'John',
    Title: 'Project Manager',
    'Hire Date': 'January 5' },
  { Name: 'Alex',
    Title: 'Accountant',
    'Hire Date': 'December 15' },
  { Name: 'Joanne',
    Title: 'Graphic Designer',
    'Hire Date': 'August 26' } ]

If your environment doesn't support Array.prototype.map function, you can use this

var result = [];
for (var i = 0; i < infoArray.length; i += 1) {
    var tempObj = {};
    for (var j = 0; j < categoryArray.length; j += 1) {
        tempObj[categoryArray[j]] = infoArray[i][j];
    }
    result.push(tempObj);
} 
 // I'm guessing that the declaration below doesn't actually assign the "Row1", "Row2", etc as nested objects like I had intended, but just re-writes a child called "row" myDict.row = {}; 

Exactly. For that, you will have to use

 myDict[row] = {};

(and the same again below: myDict[row][…] = … )

 // In theory, the first iteration of this will create a child of "row1" called "name," which will hold a value of "John" (so, the value stored infoArray[1][1]) myDict.row.categoryArray[x] = infoArray[i][x]; 

Again .categoryArray[x] is here used as a literal property name (the property x of the property "categoryArray" , which does not exist) - you will have to wrap it in brackets .

You should end up with:

var myDict = {};
for (var i = 0; i < infoArray.length; i++) { // make iteration variables local
                                             // with "var"
    var row = "row"+i; // explicit String() call not necessary
    myDict[row] = {};
    for (var x = 0; x < categoryArray.length; x++) { // again, local "x"
        myDict[row][categoryArray[x]] = infoArray[i][x];
    }
}

Using row0 , row1 , etc. doesn't sound like a good idea. An array would make more sense. Anyway:

var categoryArray = ["Name", "Title", "Hire Date"];
var infoArray = [["John","Project Manager","January 5"],["Alex","Accountant","December 15"],["Joanne","Graphic Designer","August 26"]];
var myDict = {};

for (i = 0; i < infoArray.length; i++) {
    // Each entry will be a new "row," like in a spreadsheet. 
    var row = {};
    myDict["row"+i] = row;
    // Next we iterate through the number of categories we'll need-- and we'll pull from the length of our categoryArray so we can change the number of categories later.
    for (x = 0; x < categoryArray.length; x++) {
        // In theory, the first iteration of this will create a child of "row1" called "name," which will hold a value of "John" (so, the value stored infoArray[1][1])
        row[categoryArray[x]] = infoArray[i][x];
    }
}

Output:

{
    "row0": {
        "Name": "John",
        "Title": "Project Manager",
        "Hire Date": "January 5"
    },
    "row1": {
        "Name": "Alex",
        "Title": "Accountant",
        "Hire Date": "December 15"
    },
    "row2": {
        "Name": "Joanne",
        "Title": "Graphic Designer",
        "Hire Date": "August 26"
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM