Reputation: 61
I have an array as follows:
const arr = [
{company: 'a', date: '1'},
{company: 'b', date: '1'},
{company: 'c', date: '1'},
{company: 'a', date: '2'},
{company: 'a', date: '1'},
{company: 'b', date: '2'},
]
I just want to know how to get the unique objects inside it. I tried using lodash with this command:
uniqBy(arr, 'date');
But it only returns:
[
{company: "a", date: "1"},
{company: "a", date: "2"}
]
I want something like this one:
[
{company: "a", date: "1"},
{company: "a", date: "2"},
{company: "b", date: "1"},
{company: "b", date: "2"},
{company: "c", date: "1"},
]
Is there a way in lodash or vanilla JS to have this done?
Upvotes: 5
Views: 443
Reputation: 691
This lodash function combination should do it:
_.uniqWith(arr, _.isEqual);
If you want to consider only a combination of properties for uniqueness and leave other properties out of it, you use uniqBy() with a custom function of your own that sets the criterion. For example:
const arr = [
{company: 'a', date: '1', clients: 3},
{company: 'b', date: '1', clients: 2},
{company: 'c', date: '1', clients: 2},
{company: 'a', date: '1', clients: 1}
]
const uniqArr = _.uniqBy(arr, function(obj){
return obj.company + obj.date;
});
// => [
{company: 'a', date: '1', clients: 3},
{company: 'b', date: '1', clients: 2},
{company: 'c', date: '1', clients: 2}
]
In this example, the client property does not affect uniqueness, so the last object will be excluded because the company and date properties are the same as the first object.
Upvotes: 5
Reputation: 11001
Here with using reduce
method in one line.
const arr = [
{ company: "a", date: "1" },
{ company: "b", date: "1" },
{ company: "c", date: "1" },
{ company: "a", date: "2" },
{ company: "a", date: "1" },
{ company: "b", date: "2" }
];
const updated = Object.values(
arr.reduce(
(acc, curr) => ({
...acc,
[`${curr.company}-${curr.date}`]: { ...curr }
}),
{}
)
);
console.log(updated);
Upvotes: 1
Reputation: 36564
With help of reduce()
in pure js you I created a function which takes an array of objects and array of keys as inputs and return the array which is unique by all those keys.
Following are the steps of the algorithm:
reduce()
. key
of that object will be the values of required keys which are provided each joined by -
(I mentioned keyString
for each object in the comment of code). keyString
means same values for given array of keys
will automatically occur only once because object can't have duplicate keysObject.values()
to to create an array.const arr = [
{company: 'a', date: '1'}, //keyString = "a-1"
{company: 'b', date: '1'}, //keyString = "b-1"
{company: 'c', date: '1'}, //keyString = "c-1"
{company: 'a', date: '2'}, //keyString = "a-2"
{company: 'a', date: '1'}, //keyString = "a-1"
{company: 'b', date: '2'}, //keyString = "b-2"
//The item at index 0 and index 4 have same keyString so only a single of them will remain in object.
]
const uniqueBy = (arr, keys) => {
const obj = arr.reduce((ac, a) => {
let keyString = keys.map(k => a[k]).join('-');
ac[keyString] = a;
return ac;
}, {});
return Object.values(obj);
}
console.log(uniqueBy(arr, ['company', 'date']))
Upvotes: 7
Reputation: 5853
Group them using company and date fields and use reduce
const arr = [{
company: 'a',
date: '1'
},
{
company: 'b',
date: '1'
},
{
company: 'c',
date: '1'
},
{
company: 'a',
date: '2'
},
{
company: 'a',
date: '1'
},
{
company: 'b',
date: '2'
},
];
const res = Object.values(arr.reduce((acc, curr) => {
const key = ['company', 'date'].map(x => curr[x]).join('-');
if (!acc[key]) {
acc[key] = curr;
}
return acc;
}, {}));
console.log(res);
Upvotes: 2