3

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..

5
  • 5
    I apologise for the lack of mathematical acumen, but could you explain how "pivoting" works? I can't spot the pattern Commented Oct 24, 2012 at 22:16
  • Reference point, X Y Z coords I'd guess. Commented Oct 24, 2012 at 22:17
  • @Asad: pivot is like a cross tab where you transpose a column into a row. en.wikipedia.org/wiki/Pivot_table Commented Oct 24, 2012 at 23:42
  • @Txoov I see. Does my attempt work for you? Commented Oct 25, 2012 at 10:57
  • Any libraries out there to do this? Commented Feb 12, 2023 at 16:59

3 Answers 3

2

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
   ]
}
Sign up to request clarification or add additional context in comments.

Comments

1

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

1 Comment

The test if (currItem[0] !== lastItem) would probably break, I could make it work with an Array.indexOf/filter search but if I remember correctly from my father's pivoting, those should come in order.
1

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;
})

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.