Reputation: 171
My collection contains the following (array of objects):
[
{
id: 'id-1',
uniqueName: 'operation-level-1',
operations: [
{
name: 'operaion-1',
label: 'operation-1-label'
},
{
name: 'operaion-2',
label: 'operation-2-label'
}
]
},
{
id: 'id-2',
uniqueName: 'operation-level-2'
operations: [
{
name: 'operaion-1',
label: 'operation-1-label'
},
{
name: 'operaion-3',
label: 'operation-3-label'
}
]
}
]
I wanted to get an array of unique operation name and label as shown below
const result = [
{
name: 'operaion-1',
label: 'operation-1-label'
},
{
name: 'operaion-2',
label: 'operation-2-label'
},
{
name: 'operaion-3',
label: 'operation-3-label'
}
]
Can someone suggest the best way to achieve this, please?
Upvotes: 2
Views: 2948
Reputation: 191976
Use _.flatMap()
to get a flattened array of operations
, and then use _.uniqBy()
to get only items with unique name
:
const data=[{ id: 'id-1', uniqueName: 'operation-level-1', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-2', label: 'operation-2-label' } ] }, { id: 'id-2', uniqueName: 'operation-level-2', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-3', label: 'operation-3-label' } ] }];
const result = _.uniqBy(
_.flatMap(data, 'operations'),
'name'
);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
With lodash/fp you can generate a function using _.flow()
that flattens operations
, and then get the unique values by name
:
const fn = _.flow(
_.flatMap('operations'),
_.uniqBy('name')
)
const data=[{ id: 'id-1', uniqueName: 'operation-level-1', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-2', label: 'operation-2-label' } ] }, { id: 'id-2', uniqueName: 'operation-level-2', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-3', label: 'operation-3-label' } ] }];
const result = fn(data);
console.log(result);
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
Upvotes: 5
Reputation: 5308
This can be easily done without lodash
. You can first flat the data then map
it as a key value pair and then make use of Map
to remove the duplicate entries:
var data=[{ id: 'id-1', uniqueName: 'operation-level-1', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-2', label: 'operation-2-label' } ] }, { id: 'id-2', uniqueName: 'operation-level-2', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-3', label: 'operation-3-label' } ] }];
var result = [...new Map(data.flatMap(({operations})=>operations).map(k=>([k.name, k]))).values()];
console.log(result);
Or if you do not want to use Map
then use filter
method:
var data=[{ id: 'id-1', uniqueName: 'operation-level-1', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-2', label: 'operation-2-label' } ] }, { id: 'id-2', uniqueName: 'operation-level-2', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-3', label: 'operation-3-label' } ] }];
var result = data.flatMap(({operations})=>operations).filter((val,i,self)=>self.findIndex(j=>j.name==val.name && j.label==val.label)==i);
console.log(result);
Upvotes: 6
Reputation: 23505
There is no need for loadash, a simple Map
object, will allow you to suppress the duplicates.
const arr = [{
id: 'id-1',
uniqueName: 'operation-level-1',
operations: [{
name: 'operaion-1',
label: 'operation-1-label'
},
{
name: 'operaion-2',
label: 'operation-2-label'
}
]
},
{
id: 'id-2',
uniqueName: 'operation-level-2',
operations: [{
name: 'operaion-1',
label: 'operation-1-label'
},
{
name: 'operaion-3',
label: 'operation-3-label'
}
]
}
];
// Go thought the arr and add all the name/label into the map
// Then use Array.from to reformate the Map into the wanted format
const uniqueArr = Array.from(arr.reduce((tmp, {
operations,
}) => {
operations.forEach(({
name,
label,
}) => {
tmp.set(name, label);
});
return tmp;
}, new Map())).map(([name, label]) => ({
name,
label,
}));
console.log(uniqueArr);
Upvotes: 0