Txoov
Txoov

Reputation: 174

How to pivot a javascript array

I have this javascript array:

[['a', 'x', 1],
 ['a', 'y', 2],
 ['b', 'x', 3],
 ['b', 'z', 4],
 ['c', 'y', 5],
 ['c', 'z', 6]]

How do I pivot it to something like below with the 2nd column ('x', 'y', 'z') from above going across.

[['a', 1, 2, null],
 ['b', 3, null, 4],
 ['c', null, 5, 6]]

EDIT: Sorry I was unclear. The answers so far seem to be referencing a static length/value for x, y, z. The array will be dynamic and can have anything in the 2nd column (ex. 't','u','v','w' instead of 'x','y','z'). I think I need to fill the array up first with nulls for all the possible combinations and then push in the values.

Thanks..

Upvotes: 3

Views: 18936

Answers (3)

user1726343
user1726343

Reputation:

Going by Fabricio's comment, here is how you can accomplish something similar:

var result = {};
for(var i=0;i< basearray.length;i++){
    if(!result[basearray[i][0]]){
        result[basearray[i][0]]={};
    }
    result[basearray[i][0]][basearray[i][1]]=basearray[i][2];
}

Note that this returns an object or hashmap, not strictly an array, but the data is more organised and it can easily be turned into an array if you so wish. Here is a demonstration (check your console).

By adding this code:

var count=0;
for(var key in result){
    result[count]=[];
    result[count][0]=key;
    result[count][1]=result[key].x||null;
    result[count][2]=result[key].y||null;
    result[count][3]=result[key].z||null;
    count++;
}

your result object now simulates both structures, your original array of arrays, and the suggested key value pairs. You can see the results here: http://jsfiddle.net/9Lakw/3/

Here is what result looks like:

{
   "a":{
      "x":1,
      "y":2
   },
   "b":{
      "x":3,
      "z":4
   },
   "c":{
      "y":5,
      "z":6
   },
   "0":[
      "a",
      1,
      2,
      null
   ],
   "1":[
      "b",
      3,
      null,
      4
   ],
   "2":[
      "c",
      null,
      5,
      6
   ]
}

Upvotes: 2

Eric
Eric

Reputation: 97591

Are you sure that's the format you want? It seems more sensible to get:

{
    a: {x: 1, y: 2},
    b: {x: 3, z: 4},
    c: {y: 5, z: 6}
}

Which you can get from:

var results = {};
data.forEach(function(el) {
    var name = el[0];
    var prop = el[1];
    var value = el[2];
    results[name] = results[name] || {};
    results[name][prop] = value;
})

Upvotes: 1

Fabr&#237;cio Matt&#233;
Fabr&#237;cio Matt&#233;

Reputation: 70159

Here's how I'd do it, with arrays and null fillers as in the question. This assumes that coords for given points always come in succession.

var arr = [['a', 'x', 1],
 ['a', 'y', 2],
 ['b', 'x', 3],
 ['b', 'z', 4],
 ['c', 'y', 5],
 ['c', 'z', 6]];

var aux = {
        x: 1,
        y: 2,
        z: 3
    },
    output = [],
    lastItem,
    currItem;

for (var i = 0; i < arr.length; i++) {
    currItem = arr[i];
    if (currItem[0] !== lastItem) {
        lastItem = currItem[0];
        output.push([lastItem, null, null, null]);
    }
    output[output.length-1][aux[currItem[1]]] = currItem[2];
}
console.log(output); //[["a", 1, 2, null], ["b", 3, null, 4], ["c", null, 5, 6]]

Fiddle

Upvotes: 1

Related Questions