简体   繁体   中英

Sorting an array of objects into arrays by unique key

I'm pretty rookie at this stuff so I'm expecting that I'm simply missing something extremely obvious but here's the question...

I am getting an unknown amount of objects back from a JSON call, I need to match all object keys and put them in their own array. The problem is that I don't know how many objects are in each array, to show my problem this is a very simplified version of the data I am receiving.

resultOfCall = [
  {
    'x': 'Lorem',
    'y': 'ipsum',
    'z': 'dolor'
  },
  {
    'x': 'sit',
    'y': 'amet',
    'z': 'asdf',
    'a': 'qwerty'
  },
  {
    'x': 'consectetur',
    'y': 'adipiscing',
    'z': 'elit'
  }
]

I want to take this data and create an array for every unique key so the above data would look like this...

var a = ['qwerty'];
var x = ['lorem','sit','consectetur'];
var y = ['ipsum', 'amet', 'adipiscing'];
var z = ['dolor', 'asdf', 'elit'];

Now the glaring problem with my above data is that I still need to know that x is called 'x'.

A few things to note about the data I'm receiving, I don't know how many objects I'm getting back, and I don't know how long any of those objects are. I just need to match all the keys that I get back.

You can use additional object for storing your arrays and Array.prototype.forEach function only, see example

 var resultOfCall = [ { 'x': 'Lorem', 'y': 'ipsum', 'z': 'dolor' }, { 'x': 'sit', 'y': 'amet', 'z': 'asdf', 'a': 'qwerty' }, { 'x': 'consectetur', 'y': 'adipiscing', 'z': 'elit' } ]; var obj = {}; resultOfCall.forEach(function(e) { Object.keys(e).forEach(function(k) { if (obj[k]) { obj[k].push(e[k]); } else { obj[k] = [e[k]]; } }); }); document.write('<pre>' + JSON.stringify(obj,0,2) + '</pre>');

Store the vars as key/value pairs in an object using reduce :

var obj = resultOfCall.reduce(function (p, c) {
  Object.keys(c).forEach(function (el) {
    p[el] = p[el] || [];
    p[el].push(c[el]);
  });
  return p;
}, {});

OUTPUT

{
  "x": [
    "Lorem",
    "sit",
    "consectetur"
  ],
  "y": [
    "ipsum",
    "amet",
    "adipiscing"
  ],
  "z": [
    "dolor",
    "asdf",
    "elit"
  ],
  "a": [
    "qwerty"
  ]
}

DEMO

A version which takes the keys and makes global variables with the array.

 var resultOfCall = [{ 'x': 'Lorem', 'y': 'ipsum', 'z': 'dolor' }, { 'x': 'sit', 'y': 'amet', 'z': 'asdf', 'a': 'qwerty' }, { 'x': 'consectetur', 'y': 'adipiscing', 'z': 'elit' }]; void function (data) { var r = window; data.forEach(function (a) { Object.keys(a).forEach(function (k) { r[k] = r[k] || []; r[k].push(a[k]); }); }); }(resultOfCall); document.write('<pre>a: ' + JSON.stringify(a, 0, 4) + '</pre>'); document.write('<pre>x: ' + JSON.stringify(x, 0, 4) + '</pre>'); document.write('<pre>y: ' + JSON.stringify(y, 0, 4) + '</pre>'); document.write('<pre>z: ' + JSON.stringify(z, 0, 4) + '</pre>');

Alternative a solution which returns an object with the grouped keys.

 var resultOfCall = [{ 'x': 'Lorem', 'y': 'ipsum', 'z': 'dolor' }, { 'x': 'sit', 'y': 'amet', 'z': 'asdf', 'a': 'qwerty' }, { 'x': 'consectetur', 'y': 'adipiscing', 'z': 'elit' }], grouped = function (data) { var r = {}; data.forEach(function (a) { Object.keys(a).forEach(function (k) { r[k] = r[k] || []; r[k].push(a[k]); }); }); return r; }(resultOfCall); document.write('<pre>' + JSON.stringify(grouped, 0, 4) + '</pre>');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM