1

Given this JS object list:

var items = [
{ 
'name':'a',
'id':'ab-1',
'attr':'value1'
},
{ 
'name':'c',
'id':'ab-2',
'attr':'value0'
},
{ 
'name':'z',
'id':'ab-1',
'attr':'value2'
},
{ 
'name':'t',
'id':'ab-2',
'attr':'value3'
}    
]

Is there a nice way to create a list of lists where each list contains objects with common id, like so:

 var items = [
 [
    { 
    'name':'a',
    'id':'ab-1',
    'attr':'value1'
    },
    { 
    'name':'z',
    'id':'ab-1',
    'attr':'value2'
    }],
    [
    { 
    'name':'c',
    'id':'ab-2',
    'attr':'value0'
    },        
    { 
    'name':'t',
    'id':'ab-2',
    'attr':'value3'
    }    ]
    ]

I can only think of looping through all items first to create a list of unique ids (let's call it id-list) and then looping through all items again this time creating a list for each item in id-list.

0

2 Answers 2

0

You could group it with a hash table

var items = [{ name: 'a', id: 'ab-1', attr: 'value1' }, { name: 'c', id: 'ab-2', attr: 'value0' }, { name: 'z', id: 'ab-1', attr: 'value2' }, { name: 't', id: 'ab-2', attr: 'value3' }],
    grouped = [];

items.forEach(function (a) {
    this[a.id] || grouped.push(this[a.id] = []);
    this[a.id].push(a);
}, Object.create(null));

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

Comments

0

Do it using Array#reduce method with an additional reference object which holds index.

// object for storing the reference index
var ref = {};

// iterate over array and generate result object
var res = items.reduce(function(arr, o) {
  // check index defined in `ref`
  if (ref.hasOwnProperty(o.id))
  // if defined then push value to that index
    arr[ref[o.id]].push(o);
  // else add index and push new array as element
  else {
    ref[o.id] = arr.length;
    arr.push([o]);
  }
  // return the array reference
  return arr;
  // set initial valaue as empty array
}, []);

var items = [{
  'name': 'a',
  'id': 'ab-1',
  'attr': 'value1'
}, {
  'name': 'c',
  'id': 'ab-2',
  'attr': 'value0'
}, {
  'name': 'z',
  'id': 'ab-1',
  'attr': 'value2'
}, {
  'name': 't',
  'id': 'ab-2',
  'attr': 'value3'
}];

// object for storing the reference index
var ref = {};

// iterate over array and generate result object
var res = items.reduce(function(arr, o) {
  // check index defined in `ref`
  if (ref.hasOwnProperty(o.id))
  // if defined then push value to that index
    arr[ref[o.id]].push(o);
  // else add index and push new array as element
  else {
    ref[o.id] = arr.length;
    arr.push([o]);
  }
  // return the array reference
  return arr;
  // set initial valaue as empty array
}, []);


console.log(res);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.