-2

I have an array of objects. I need to group them by name and then combine another property in an array.

[
   {
      NAME: 'TEST_1',
      ID: '1',
      FROM: '20191223',
      TO: '99991231'
    },

   {
      NAME: 'TEST_1',
      ID: '2',
      FROM: '20191223',
      TO: '99991231'
   },

   {
      NAME: 'TEST_2',
      ID: '3',
      FROM: '20191223',
      TO: '99991231'
   },
   {
      NAME: 'TEST_2',
      ID: '4',
      FROM: '20191223',
      TO: '99991231'
   },
]

Any my output will be:

[
 {
  NAME: 'TEST_1',
  ID: '[1, 2]',
  FROM: '20191223',
  TO: '99991231'
 },

 {
  NAME: 'TEST_2',
  ID: '[3, 4]',
  FROM: '20191223',
  TO: '99991231'
},
]
user2281858
  • 1,957
  • 10
  • 41
  • 82
  • What have you tried, it looks like it would be enough to reduce (aggregate) the array based on the `name` property. Seeing you have some rep on the site would indicate that you do know how the Q&A works here – Icepickle Jan 24 '20 at 15:10
  • Probable duplicate of [Group array items using object](https://stackoverflow.com/q/31688459/215552)... – Heretic Monkey Jan 24 '20 at 15:43

3 Answers3

1

const input = [
   {
      NAME: 'TEST_1',
      ID: '1',
      FROM: '20191223',
      TO: '99991231'
    },

   {
      NAME: 'TEST_1',
      ID: '2',
      FROM: '20191223',
      TO: '99991231'
   },

   {
      NAME: 'TEST_2',
      ID: '3',
      FROM: '20191223',
      TO: '99991231'
   },
   {
      NAME: 'TEST_2',
      ID: '4',
      FROM: '20191223',
      TO: '99991231'
   },
];


const output = input.reduce((group, {NAME, ID, FROM, TO}) => {
  group[NAME] = group[NAME] || { NAME, FROM, TO };
  
  group[NAME].ID = group[NAME].ID || [];
  group[NAME].ID.push(ID);

  return group;
}, {});

console.log(Object.values(output));
ajai Jothi
  • 2,284
  • 1
  • 8
  • 16
1

const data = [{
    NAME: 'TEST_1',
    ID: '1',
    FROM: '20191223',
    TO: '99991231'
  },

  {
    NAME: 'TEST_1',
    ID: '2',
    FROM: '20191223',
    TO: '99991231'
  },

  {
    NAME: 'TEST_2',
    ID: '3',
    FROM: '20191223',
    TO: '99991231'
  },
  {
    NAME: 'TEST_2',
    ID: '4',
    FROM: '20191223',
    TO: '99991231'
  },
].reduce((tmp, {
  NAME,
  ID,
  ...args
}) => {
  const alreadyIn = tmp.find(x => x.NAME === NAME);

  if (alreadyIn) {
    alreadyIn.ID.push(ID);
  } else {
    tmp.push({
      NAME,
      ID: [ID],
      ...args,
    });
  }

  return tmp;
}, []);

console.log(data);
Orelsanpls
  • 22,456
  • 6
  • 42
  • 69
1

Use reduce to make an object for an easy look up, convert the id to an array.

const data = [
   {
      NAME: 'TEST_1',
      ID: '1',
      FROM: '20191223',
      TO: '99991231'
    },

   {
      NAME: 'TEST_1',
      ID: '2',
      FROM: '20191223',
      TO: '99991231'
   },

   {
      NAME: 'TEST_2',
      ID: '3',
      FROM: '20191223',
      TO: '99991231'
   },
   {
      NAME: 'TEST_2',
      ID: '4',
      FROM: '20191223',
      TO: '99991231'
   },
]

const combined = data.reduce((obj, item) => {
  var name = item.NAME
  if (obj[name]) {
    obj[name].ID.push(item.ID)
  } else {
    obj[name] = {
      ...item,
      ID: [item.ID]
    }
  }
  return obj
}, {})

const result = Object.values(combined)
console.log(result)
epascarello
  • 204,599
  • 20
  • 195
  • 236