1

I want to write a function that takes an array such as:

var columns = ['distance', 'times', 'acceleration']

Then from this array, I want to generate something like this:

[{id: id_0, distance: 0, times: 0, acceleration: 0}, {id: id_1, distance: 1, times: 1, acceleration: 1}]

Notice that we have 2 objects here, but I want it to be whatever number I pass in to my parameter. Here is what I have:

generateData: function(rows, columns) {
  var generatedData = [];
  for (var i = 0, rowLen = rows.length; i < rowLen; i++) {
    for (var n = 0; i < columns.length; n++) {
      // not sure how to construct an object here from looping through my columns array
      generatedData.push({
      id: 'id_ + n',
      // confused here
      });
    }
  return generatedData;
  }
}

3 Answers 3

2

This is the perfect place to dynamically create your own function. Try this:

function createArrayOfObjects(columns, count) {
  var objectProps = new Array(columns.length);
  for (var i = 0; i < columns.length; i++){
    //":j" will be the variable j inside the dynamic function
    objectProps[i] = columns[i] + ":j";
  }

  var funcBody = "var arr = new Array(count);" +
      "for(var j = 0; j < count; j++){" +
          "arr[j] = {" + objectProps.join(',') + "};" +
      "}" +
      "return arr;";

  //Create a new function and call it with count as the parameter, returning the results
  return new Function("count", funcBody)(count);
}

var count = 10;
var columns = ['distance', 'times', 'acceleration'];

createArrayOfObjects(columns.concat('id'), count);

This has the benefit of only having to loop over the columns array once where other solutions require nested loops.

JSPerf

Sign up to request clarification or add additional context in comments.

3 Comments

Hm, last time I tested this approach it didn't proof to be a lot faster. It seems to work here, however. +1 for the effort, but I think it's not necessary for OP and he should use the trivial (and short) solution.
@Bergi, I would argue that this solution(10 lines of code, or 6 depending on how you count the funcBody string) is the same length as the trivial solution (10 lines of code)
Oh, that's right, I misjudged it from the appearance of your snippet. However, dealing with code strings is still errorprone, e.g. if the columns are no valid identifier names your code would fail.
1

I am giving you away the initial non-optimized solution. Its upto you to do the optimizations.

generateData: function(rows, columns) {
  var generatedData = [];
  for (var i = 0; i < rows.length; i++) {
      var myObj = {};
      myObj["id_" + i] = i;
      for (var n = 0; n < columns.length; n++) {
          myObj[columns[n]] = i;
      }
      generatedData.push(myObj);
  }
  return generatedData;
}

2 Comments

What optimisations are you talking about?
@Bergi See my answer for an optimized version.
1

A functional approach that will take the object properties from the passed in array, instead of hard-coding them, might look something like this inside the for loop to populate an array named 'rows' with property names coming from the values of an array named 'cols':

cols.forEach(function(cv, ci, ca) { rows[ri][cv] = ri; });

See the snippet for a full example. Note that, in this example, I'm just shoving the current index of "rows" into the object as the property value.

var columns = ['distance', 'times', 'acceleration'];

function generateData(numRows, cols) {
    rows = new Array(numRows);
    for(ri=0; ri < rows.length; ri++) {
        rows[ri] = { id: ri };
        cols.forEach(function(cv, ci, ca) {
            rows[ri][cv] = ri;
        });
    }
    return rows;
}


data = generateData(5, columns);
console.log(data);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.