Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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

share|improve this question

2 Answers 2

up vote 3 down vote accepted

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;
    }, {});
  });
}
share|improve this answer
    
It is clear to me now that, indeed, it doesn't 'make an object property'! –  paddytag Jul 8 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/

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.