# Create an array of objects from array of arrays

I have the following function that creates an array of JSON objects with properties from an array of arrays, where the first 'row' in the array contains the keys.

It works, but could it be improved?

var myArray = [
["a","b","c","d"], // will become keys
[1,2,3,4],
["foo","bar","baz","bob"]
];

function makeObjProp(arr) {

var keys = arr[0];
var numRows = arr.length;
var numCols = keys.length;

var result = [];

// starts i = 1 to avoid adding an object of 'keys':'keys'
for (var i = 1; i < numRows; i++) {
var obj = {};

for (var j = 0; j < numCols; j++) {
obj[ keys[j] ] = arr[i][j];
};
result.push(obj);
};
console.log(result);
}

makeObjProp(myArray);


fiddle

-

I don't see any significantly better way of doing this. It can be written in different ways (like below), but yours is pretty simple and straightforward.

That said, you'll probably want your function to actually return the new array instead of just logging it.

And you'll want some error checking. I'd say you should assume that an array has been passed in (if it isn't, well, that's not really this function's responsibility. Garbage In, Garbage Out), but don't assume it's actually populated. So check that it contains at least 2 rows.

You may also want to check that the items in the array are also arrays, though again: GIGO.

And I'd rename the function. It doesn't "make an object property" as its name suggests; it converts an entire array to objects, following some scheme. I can't quite say what that better name might be, though. The input resembles tabular data (header row, etc.), so maybe something along those lines.

If you're targeting modern browsers, you could do some map/reduce stuff instead:

function rowsToObjects(table) {
var keys = table[0],
rows = table.slice(1);

if(rows.length === 0) return [];

return rows.map(function (row) {
return keys.reduce(function (memo, key, index) {
memo[key] = row[index];
return memo;
}, {});
});
}

-
It is clear to me now that, indeed, it doesn't 'make an object property'! –  pompon Jul 8 '14 at 13:00

You can use Slice and Transpose, but your code is not that bad - just add some syntactic sugar by refactoring the code and:

function Map(arr, i) {
var obj = {};
for (var j = 0; j < arr[0].length; j++) {
obj[ arr[0][j] ] = arr[i][j];
};
return obj;
}
function BuildJSON(arr) {
var result = [];
for (var i = 1; i < arr.length; i++) {
result.push(Map(arr, i));
};
return JSON.stringify(result);
}

$(function() { var myArray = [ ["a","b","c","d"], [1,2,3,4], ["foo","bar","baz","bob"] ]; var val = BuildJSON(myArray);$('#result').text(val);
});


http://jsfiddle.net/gbJY4/5/

-