I have an array of object having with multiple value but I have to filter values based on keys into an array and also merge value to array having same value. I have tried in different steps can it be done in single map/filter/reduce?
const a = [
{abc: ['add', 'edit'], cond: []},
{cond: ['add_cond', 'edit_cond', 'view_cond'], matx: ['add_matx', 'edit_matx', 'delete_matx'], work: ['add_work', 'edit_work'], def: []},
{cond: ['add_cond', 'edit_cond', 'view_cond', 'delete_cond'], matx: ['add_matx', 'edit_matx', 'view_matx', 'store_matx'], work: ['view_work', 'delete_work']},
];
const expected result = {
cond: ['add_cond', 'edit_cond', 'view_cond', 'delete_cond'], matx: ['add_matx', 'edit_matx', 'view_matx', 'store_matx', 'delete_matx'], work: ['add_work', 'edit_work','view_work', 'delete_work']
}
const b = a.map(el => el.cond);
const c = a.map(el => el.matx);
const d = a.map(el => el.work);
result = {cond: [...b], matx: [...c], work: [...d]}
You could collect all wanted properties' values into a set and build a new object from the key/value pairs.
const
data = [{ abc: ['add', 'edit'], cond: [] }, { cond: ['add_cond', 'edit_cond', 'view_cond'], matx: ['add_matx', 'edit_matx', 'delete_matx'], work: ['add_work', 'edit_work'], def: [] }, { cond: ['add_cond', 'edit_cond', 'view_cond', 'delete_cond'], matx: ['add_matx', 'edit_matx', 'view_matx', 'store_matx'], work: ['view_work', 'delete_work'] }],
keys = ['cond', 'matx', 'work'],
addToSet = (s, v) => s.add(v),
result = Object.fromEntries(keys.map(k => [
k,
[...data.reduce((r, o) => (o[k] || []).reduce(addToSet, r), new Set)]
]));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can achieve this using a single reduce method. All keys are evaluated dynamically, so no matter how many keys you add/remove to your objects you get dynamically added keys:
const a = [
{abc: ['add', 'edit'], cond: []},
{cond: ['add_cond', 'edit_cond', 'view_cond'], matx: ['add_matx', 'edit_matx', 'delete_matx'], work: ['add_work', 'edit_work'], def: []},
{cond: ['add_cond', 'edit_cond', 'view_cond', 'delete_cond'], matx: ['add_matx', 'edit_matx', 'view_matx', 'store_matx'], work: ['view_work', 'delete_work']},
];
const result = a.reduce((prev, cur) => {
// get all keys
const keys = Object.keys(cur);
// add each key and related values one by one
keys.forEach(el => {
if(prev[el] === undefined)
prev[el] = []
prev[el].push(cur[el])
// remove duplicates
prev[el] = prev[el].flat()
})
return prev
}, {})
console.log(result)
It can be done with forEach ... .map() and .filter() will always return an array not an object.
const a = [
{abc: ['add', 'edit'], cond: []},
{cond: ['add_cond', 'edit_cond', 'view_cond'], matx: ['add_matx', 'edit_matx', 'delete_matx'], work: ['add_work', 'edit_work'], def: []},
{cond: ['add_cond', 'edit_cond', 'view_cond', 'delete_cond'], matx: ['add_matx', 'edit_matx', 'view_matx', 'store_matx'], work: ['view_work', 'delete_work']},
];
const result = {cond: [], work: [], matx: []}
a.forEach(x=> { x.cond && result.cond.push(...x.cond);
x.work && result.work.push(...x.work);
x.matx && result.work.push(...x.matx);
}
);
console.log(result);