so i have a array in that a key have another array of object i need to make unique array of object from this array based on two key level and userId using lodash or vanila JavaScript
for example
const data = [
{
values: {
output: [],
}
},
{
values: {
output: [
{ level: 1, userId: "810", },
{ level: 1, userId: "811", },
{ level: 2, userId: "811", },
],
},
},
{
values: {
output: [
{ level: 1, userId: "810", },
],
}
},
{
values: {
output: [
{ level: 1, userId: "810", },
{ level: 3, userId: "810", },
],
}
},
{
values: {
output: [
{ level: 1, userId: "810", },
{ level: 3, userId: "810", },
],
}
}
];
and expected output is
let output =[
{ level: 1, userId: "810", },
{ level: 1, userId: "811", },
{ level: 2, userId: "811", },
{ level: 3, userId: "810", },
]
CodePudding user response:
Get an array of all output
properties with _.flatMap()
(or Array.flatMap()
, and then use _.uniqBy()
to get only unique items. In the _.uniqBy()
callback return a custom value by combining level
and userId
to a single string:
const data = [{"values":{"output":[]}},{"values":{"output":[{"level":1,"userId":"810"},{"level":1,"userId":"811"},{"level":2,"userId":"811"}]}},{"values":{"output":[{"level":1,"userId":"810"}]}},{"values":{"output":[{"level":1,"userId":"810"},{"level":3,"userId":"810"}]}},{"values":{"output":[{"level":1,"userId":"810"},{"level":3,"userId":"810"}]}}];
const result = _.uniqBy(
_.flatMap(data, o => o.values.output),
o => `${o.level}-${o.userId}`
);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG ljU96qKRCWh quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
CodePudding user response:
Here's a very vanilla JS solution. This won't be fast on huge data sets but for sets like your example, it's not too bad. It first gathers all of your data together into a single array and then builds a new and duplicate-free array. If you need to be careful about overwriting the data that you pass in then you can clone it first.
function mergeAllData(data) {
var allData = [];
for (var i in data) {
allData = allData.concat(data[i].values.output);
}
return allData;
}
function filterDuplicates(allData) {
var ret = [];
for (var i in allData) {
var current = allData[i];
ret.push(current);
for (var j in allData) {
if (isADuplicate(current, allData[i])) {
allData.splice(j, 1);
}
}
}
return ret;
}
function isADuplicate(t1, t2) {
return t1.level === t2.level && t1.userId === t2.userId;
}
console.log(filterDuplicates(mergeAllData()));