Combining two arrays to form a javascript object
I have two arrays:
var columns = ["Date", "Number", "Size", "Location", "Age"];
var rows = [["2001", "5", "Big", "Sydney", "25"],["2005", "2", "Med", "Melbourne", "50"],["2012", "20", "Huge", "Brisbane", "80"]];
I'm trying to combine them into a javascript object for each item in the rows array. After that, I want to push each object into a new array.
Like:
var newarray = [];
//'thing' should be the same structure for each row item
var thing = {
"Date" : "2001",
"Number" : "5",
"Size":"Big",
"Location":"Sydney",
"Age":"25"
}
newarray.push(thing);
I can do this when I know the names of the columns, but I need to be able to store the data in this way when the column name is unknown - i.e. based on the indexes of the columns array.
I tried it like this before:
for(var y = 0; y < rows.length; y++){
for(var i = 0; i < columns.length; i++){
thing[columns[i]] = rows[i][i];
}
newarray.push(thing)
}
The code above only stored the first item again and again (according to rows.length).
I don't understand how to combine the column names with the rows to create an array of objects. The fact that 'rows' contains arrays is especially confusing..
You could as well do this in a more data-centric manner:
var columns = ["Date", "Number", "Size", "Location", "Age"];
var rows = [
["2001", "5", "Big", "Sydney", "25"],
["2005", "2", "Med", "Melbourne", "50"],
["2012", "20", "Huge", "Brisbane", "80"]
];
var result = rows.map(function(row) {
return row.reduce(function(result, field, index) {
result[columns[index]] = field;
return result;
}, {});
});
This way you would not have to deal with the temporary arrays.
In case your code should work on ancient browsers as well, I'd recommend to take a look at underscore.js for using map
+ reduce
.
Create a new thing
object at the beginning of each iteration of the outer loop. If you don't do so, each time you say thing[columns[i]]
you'll be overwriting the properties of the same object, and when you push it into newarray
what you'll end up with is an array full of references to the same object. Also, inside the loop be sure you get the indexes right (you've currently got [i][i]
instead of [y][i]
):
var newarray = [],
thing;
for(var y = 0; y < rows.length; y++){
thing = {};
for(var i = 0; i < columns.length; i++){
thing[columns[i]] = rows[y][i];
}
newarray.push(thing)
}
"The fact that 'rows' contains arrays is especially confusing.."
For your sample data rows.length
will be 3, and rows[0]
is the array:
["2001", "5", "Big", "Sydney", "25"]
rows[0][3]
is "Sydney".
Using that as an example you should be able to see what rows[y][i]
will give you for each value of y
and i
...
In case you are using Underscore.js there is _.object(list, [values])
And here's how it's implemented:
_.object = function(list, values) {
if (list == null) return {};
var result = {};
for (var i = 0, length = list.length; i < length; i++) {
if (values) {
result[list[i]] = values[i];
} else {
result[list[i][0]] = list[i][1];
}
}
return result;
};
Using functional would be like nnnnnn said but with a minor correction
var columns = ["Date", "Number", "Size", "Location", "Age"];
var rows = [
["2001", "5", "Big", "Sydney", "25"],
["2005", "2", "Med", "Melbourne", "50"],
["2012", "20", "Huge", "Brisbane", "80"]
];
var result = rows.map(function(row) {
return row.reduce(function(result, field, index) {
result[columns[index]] = field;
return result
}, {});
});