1

Having an array of objects with this structure:

[
    {
        key: id,
        value: id, name, type
    },
    {   key: id,
        value: id, name, type
    },
    {   key: id,
        value: id, name, type
    }
];

The key used is the id. There could be more groups of values for the same id, like:

{ 132: Array(1), 243: Array(1), 389: Array(3)}
    132: Array(1)
        0: eqKey: "abc", id: 132, name: "name1"
    243: Array(1)
        0: eqKey: "ccc", id: 243, name: "name2"
    389: Array(3)
        0: eqKey: "vcv", id: 389, name: "name3"
        1: eqKey: "tre", id: 389, name: "name4"
        2: eqKey: "ace", id: 389, name: "name5"

My question is if it's a way to "regroup" the structure, instead of being grouped by id to be grouped by type. (Type is unique)

So the final form for the above example would look like this:

{"abc": Ar(1), "ccc": Ar(1), "vcv": Ar(1), "tre": Ar(1), "ace": Ar(1)}  
    "abc": Array(1)
        0: eqKey: "abc", id: 132, name: "name1" 
    "ccc": Array(1)
        0: eqKey: "ccc", id: 243, name: "name2"
    "vcv": Array(1)
        0: eqKey: "vcv", id: 389, name: "name3"
    "tre": Array(1)
        0: eqKey: "tre", id: 389, name: "name4"
    "ace": Array(1)
        0: eqKey: "ace", id: 389, name: "name5"
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
Leo Messi
  • 5,157
  • 14
  • 63
  • 125

4 Answers4

1

You could use two nested reduce for the outer values of the object and the inner array.

var data = { 132: [{ eqKey: "abc", id: 132, name: "name1" }], 243: [{ eqKey: "ccc", id: 243, name: "name2" }], 389: [{ eqKey: "vcv", id: 389, name: "name3" }, { eqKey: "tre", id: 389, name: "name4" }, { eqKey: "ace", id: 389, name: "name5" }] },
    grouped = Object
        .values(data)
        .reduce(
            (r, a) => a.reduce(
                (s, o) => ((r[o.eqKey] = r[o.eqKey] || []).push(o), s),
                r
            ),
            {}
        );

console.log(grouped);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

As pointed out in the comments, your second code snippet is impossible in JS. Objects must have unique keys.

However, I believe what you are trying to achieve is this:

const array = [
  {
    1: { id: 1, name: 'name', type: 'ab' }
  },
  {
    5: { id: 5, name: 'name', type: 'aa' },
    4: { id: 4, name: 'name', type: 'ac' }
  }
];

const result = array
  .reduce((arr, item) => Object
    .keys(item)
    .reduce((arr2, key) => ([...arr2, { [item[key].type]: item[key] }]), arr), []);

console.log(result);
Moritz Schmitz v. Hülst
  • 3,229
  • 4
  • 36
  • 63
0

You can use reduce to loop thru the array. Convert each object using Object.values to array and use forEach to loop thru the converted array

const arr = [{"1":{"id":1,"name":"name1","type":"xx"}},{"2":{"id":2,"name":"name2","type":"xy"}},{"5":{"id":5,"name":"name5","type":"vc"},"6":{"id":5,"name":"name6","type":"fg"},"7":{"id":5,"name":"name7","type":"ae"}}];

const result = arr.reduce((c, v) => {
  Object.values(v).forEach(o => c.push({[o.type]: o}))
  return c;
}, []);

console.log( result );

On new browsers ( Or using a profiler ), you can use flatMap

const arr = [{"1":{"id":1,"name":"name1","type":"xx"}},{"2":{"id":2,"name":"name2","type":"xy"}},{"5":{"id":5,"name":"name5","type":"vc"},"6":{"id":5,"name":"name6","type":"fg"},"7":{"id":5,"name":"name7","type":"ae"}}];

const result = arr.flatMap(o => Object.values(o).map(v => ({[v.type]: v})))

console.log(result);
Moritz Schmitz v. Hülst
  • 3,229
  • 4
  • 36
  • 63
Eddie
  • 26,593
  • 6
  • 36
  • 58
0

You can achieve your requirements using reduce method.

The reduce() method executes a reducer function (that you provide) on each member of the array resulting in a single output value.

const data = [{
    id: 1,
    name: "name1",
    type: "xx"
  },{
    id: 2,
    name: "name2",
    type: "xy"
  },{
    id: 5,
    name: "name5",
    type: "vc"
  },{
    id: 5,
    name: "name6",
    type: "fg"
  }, {
    id: 5,
    name: "name7",
    type: "ae"
  }
];

const result = data.reduce(function(r, a) {
  r[a.type] = r[a.type] || [];
  r[a.type].push(a);
  return r;
}, Object.create(null));

console.log(result);
Moritz Schmitz v. Hülst
  • 3,229
  • 4
  • 36
  • 63
dganenco
  • 1,596
  • 1
  • 5
  • 16