Skip to content Skip to sidebar Skip to footer

Segregate An Array Based On Same Name

I have an array with multiple objects having the same name. How can I segregate the array based on the name? I tried with map, filter but didn't work finally I used reduce also but

Solution 1:

You can perform a reduce operation using an object to store elements with the same name.

const arr = [{name: "audio", options:{name:'true', value: 'T'}},
{name: "audio", options:{name:'false', value: 'F'}},
{name: "audio", options:{name:'yes', value: 'Y'}},
{name: "video", options:{name:'true', value: 'T'}},
{name: "video", options:{name:'yes', value: 'Y'}},
{name: "video", options:{name:'false', value: 'F'}},
{name: "call", options:{name:'true', value: 'T'}},
{name: "call", options:{name:'No', value: 'N'}},
{name: "call", options:{name:'false', value: 'F'}}];
const res = Object.values(arr.reduce((acc,{name, options})=>{
  acc[name] = acc[name] || {name, options: []};
  acc[name].options.push(options);
  return acc;
}, {}));
console.log(res);

Solution 2:

You're on the right track using reduce, but instead of reducing to an Object, you can reduce and push items onto an Array, which should give you the output you need:

this.optionsArr.reduce((p, c) => {
   if (!p.some(a => a.name === c.name)) {
        p.push({ name: c.name, options: []});
   }
   p.find(a => a.name === c.name).options.push(c.options);
   return p;
}, []);

Solution 3:

Your code is almost correct, you just forgot to initiate options as an empty array, so the push can work:

add , options: [] to the first inline inside the reduce function

const result = Object.values(this.optionsArr.reduce((a, c) => {
        a[c.name] = a[c.name] || {name: c.name, options: []};
        a[c.name].options.push(c.options);
        return a;
      }, {})).map(item => ({...item, accessDetails: Object.values(item.accessDetails)}));

Solution 4:

This approach is a mix of a generic reduce function that will group any data-item by a given key (via configuration) and a task specific merge function that is specific for e.g. the OP's goal of how to process the properties of any data-item that is going to be merged into its belonging/related group. This method as well gets provided via the initial configuration of the reduce process ...

//  reduce function that groups//  any data item generically by key.functiongroupByKeyAndMergeProperties(collector, item) {
  const { merge, key, index, list } = collector;
  const groupKey = item[key];

  let groupItem = index[groupKey];
  if (!groupItem) {

    //  use `Object.assign` initially in order//  to not mutate the original (list's) reference.
    groupItem = index[groupKey] = Object.assign({}, item);
    list.push(groupItem);

    merge(groupItem, null);
  } else {
    merge(groupItem, item);
  }
  return collector;
}

//  task specific merge function,//  here, according to the OP's goal.functionmergeItemOptions(targetItem, sourceItem) {
  if (sourceItem === null) {
    targetItem.options = [targetItem.options];
  } else {
    targetItem.options.push(sourceItem.options);
  }
}


const sampleList = [
  {name: "audio", options:{name:'true', value: 'T'}},
  {name: "audio", options:{name:'false', value: 'F'}},
  {name: "audio", options:{name:'yes', value: 'Y'}},
  {name: "video", options:{name:'true', value: 'T'}},
  {name: "video", options:{name:'yes', value: 'Y'}},
  {name: "video", options:{name:'false', value: 'F'}},
  {name: "call", options:{name:'true', value: 'T'}},
  {name: "call", options:{name:'No', value: 'N'}},
  {name: "call", options:{name:'false', value: 'F'}}
];

console.log(
  sampleList.reduce(groupByKeyAndMergeProperties, {

    // task specific reduce configuration.merge: mergeItemOptions,
    key: 'name',
    index: {},
    list: []

  }).list
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Post a Comment for "Segregate An Array Based On Same Name"