0

I have an array like this:

var products = [
    ['date1','prod1',1,2],
    ['date2','prod2',3,4],
    ['date3','prod3',5,6],
    ['date4','prod4',7,8],
    ['date5','prod5',9,0]
];

And need to pull the integers out of the array and format it like this:

var newProductsArray = [[1,3,5,7,9],[2,4,6,8,0]];

It needs to be able to be dynamic and expand because the products array will have more "columns".

I have this code but it's doing it backwards and can't figure out how to loop through and just break up the arrays. I am sure it's something simple I'm missing.

var metricStartPosition = 2;
var dataSetInnerArray = [];
var dataSetArray = [];

for (var i = 0; i < array.length; i++) {
    for (var k = metricStartPosition; k < array[i].length; k++) {
        dataSetInnerArray.push(array[i][k]);
    };
    dataSetArray.push(dataSetInnerArray);
    dataSetInnerArray = [];
}; 
1
  • 1
    "...in a different order..." - But your results has the values in the same order as in the original array. When you talk about expanding to cater for more columns, do you mean that the items might be like ['date1','prod1',1,2,'a','b'] and thus your output array would have one nested array per column from the input? Will every item in the input always have the same number of columns as the other items? Commented Jul 9, 2016 at 2:23

4 Answers 4

2

You can do something like this:

var products = [
      ['date1','prod1',1,2,'a','b'],
      ['date2','prod2',3,4,'c','d'],
      ['date3','prod3',5,6,'e','f'],
      ['date4','prod4',7,8,'g','h'],
      ['date5','prod5',9,0,'i','j']
];
var metricStartPosition = 2;
var newProductsArray = products.reduce(function(output, item) {
  item.slice(metricStartPosition).forEach(function(v, i) {
    (output[i] || (output[i] = [])).push(v);
  });
  return output;
}, []);
console.log(JSON.stringify(newProductsArray));

Should work with any number of columns.

Of course you could use nested .forEach() loops or old-school nested for loops instead of .forEach() inside .reduce().

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

2 Comments

Nice use of reduce.
@ZombieCode - Thanks. In this case I admit .reduce() doesn't really give you much of a benefit compared to setting newProductsArray = []; before a nested .forEach() loop that adds to newProductsArray directly, but of course once you start using .reduce() you tend to want to use it for everything, and this way does feel a little more self-contained.
1

If I got your question correctly, inverting the order of the two for loops will do it:

var metricStartPosition = 2;
var dataSetInnerArray = [];
var dataSetArray = [];

for (var k = metricStartPosition; k < products[0].length; k++) {
     for (var i = 0; i < products.length; i++) {

        dataSetInnerArray.push(products[i][k]);
    };
    dataSetArray.push(dataSetInnerArray);
    dataSetInnerArray = [];
};

Comments

0

Related Post

This should flip the array.

var newArray = array[0].map(function(col, i) { 
  return array.map(function(row) { 
    return row[i] 
  })
});

As a function this is:

function foo (array) {
    var newArray = array[0].map(function(col, i) { 
        return array.map(function(row) { 
            return row[i] 
        })
    });
    return newArray;
}

By flip the array I mean this:

1 2 3      1 4 7
4 5 6  ->  2 5 8
7 8 9      3 6 9

And in your case:

var products = [
    ['date1','prod1',1,2],
    ['date2','prod2',3,4],
    ['date3','prod3',5,6],
    ['date4','prod4',7,8],
    ['date5','prod5',9,0]
];

var newProducts = [
    ['date1','date2','date3','date4','date5'],
    ['prod1','prod2','prod3','prod4','prod5'],
    [1,3,5,7,9],
    [2,4,6,8,0]
];

Comments

0

You could try and index all the columns one-by-one (assuming all the rows of the data is of the same types column-wise:

arrayRow = products[0] //['date1','prod1',1,2]
newProductsArray = [];
intIndices = [];
arrayRow.forEach(function(data, i) {
  if (typeof(data) === 'number')
    intIndices.push(i);
});

// intIndices should be [2, 3]

and then iterate through the whole products array to get all the columns:

intIndices.forEach(function (colIndex) {
  innerArray = [];
  for (var i = 0; i < products.length; i++) {
    innerArray.push(products[i][colIndex]);
  }
  newProductsArray.push(innerArray);
});

// you should get nested arrays with all the integer columns
// [ [ 1, 3, 5, 7, 9 ],
//   [ 2, 4, 6, 8, 0 ] ]

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.