Segregate An Array Based On Same Name
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"