0

Data array

[
 {group: 'a', tab: "1", name: 'input1'},
 {group: 'b', tab: "1", name: 'input2'},
 {group: 'b', tab: "1", name: 'input3'},
 {group: 'c', tab: "2", name: 'input4'},
 {group: 'a', tab: "1", name: 'input5'},
 {group: 'c', tab: "2", name: 'input6'},
];

Every array element (there are over 50 of these) is one input which belongs to one group (a, b or c) and tab (1, 2, etc.) in my application. What I want to do is to check how many groups one tab has, get an object or array which looks like this:

 [
      {tab1:{groups: ["a", "b"]}},
      {tab2:{groups: ["c"]}},
    ]
Shiv Kumar Baghel
  • 2,464
  • 6
  • 18
  • 34
hames
  • 93
  • 12
  • 3
    Possible duplicate of [How to group an array of objects by key](https://stackoverflow.com/questions/40774697/how-to-group-an-array-of-objects-by-key) – Luca Kiebel Sep 23 '18 at 15:38

4 Answers4

1

You can simply use Array.reduce() to create a map and group it by Tab, Object.values() on the map will give you the desired result.

let arr =[ {group: "a", tab: "1", name: "input1"}, {group: "b", tab: "1", name: "input2"}, {group: "b", tab: "1", name: "input3"}, {group: "c", tab: "2", name: "input4"}, {group: "a", tab: "1", name: "input5"}, {group: "c", tab: "2", name: "input6"}];

let result = Object.values(arr.reduce((a, {group, tab})=>{
  a[tab] = a[tab] || {["tab"+tab] : {group : []}};
  if(!a[tab]["tab"+tab].group.includes(group))
    a[tab]["tab"+tab].group.push(group);
  return a;
},{}));

console.log(result);

:

amrender singh
  • 7,949
  • 3
  • 22
  • 28
1

We can use Set to create a unique array, and use map to manipulate each array item and filter to remove elements from the array. So what I did is this:

  1. Get a unique list of tabs.
  2. Map the list to create a new object for each tab
    1. Use a filter to to find tabs of the particular type
    2. Map that filter to get just the group letter
    3. Create a set again for a unique list of group letters.
  3. Finally the new object is returned back to the first map item to get an array of items.

It looks like this:

let data = [
 {group: 'a', tab: "1", name: 'input1'},
 {group: 'b', tab: "1", name: 'input2'},
 {group: 'b', tab: "1", name: 'input3'},
 {group: 'c', tab: "2", name: 'input4'},
 {group: 'a', tab: "1", name: 'input5'},
 {group: 'c', tab: "2", name: 'input6'},
];

let tabs = [...new Set(data.map(itm => itm.tab))].map(tab => {
  return {
    ['tab' + tab]: {groups: [...new Set(data.filter(i => i.tab == tab).map(i => i.group))]}
  }
})

console.log(tabs)
Get Off My Lawn
  • 34,175
  • 38
  • 176
  • 338
0

You could use a Map for grouping and Set for collecting unique values.

var data = [{ group: 'a', tab: '1', name: 'input1' }, { group: 'b', tab: '1', name: 'input2' }, { group: 'b', tab: '1', name: 'input3' }, { group: 'c', tab: '2', name: 'input4' }, { group: 'a', tab: '1', name: 'input5' }, { group: 'c', tab: '2', name: 'input6' }],
    result = Array.from(
        data.reduce(
            (m, { tab, group }) => m.set(tab, (m.get(tab) || new Set).add(group)),
            new Map
        ),
        ([tab, groups]) => ({ ['tab' + tab]: { groups: Array.from(groups) } })
    );
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

Try next code

const src = [
  { group: "a", tab: "1", name: "input1" },
  { group: "b", tab: "1", name: "input2" },
  { group: "b", tab: "1", name: "input3" },
  { group: "c", tab: "2", name: "input4" },
  { group: "a", tab: "1", name: "input5" },
  { group: "c", tab: "2", name: "input6" },
];

const convert = (src) => {
  const dst = [];
  Object.keys(src).forEach((item) => {
    const tab = `tab${src[item].tab}`;
    // Check if dst[tab] does not exist
    if (typeof (dst[tab]) === 'undefined') {
      dst[tab] = { groups: [] };
    }
    // Check if groups contains group
    if (!dst[tab].groups.includes(src[item].group)) {
      dst[tab].groups.push(src[item].group);
    }
  });
  return dst;
};

console.log(convert(src));
Sanchonn
  • 179
  • 6