What I am trying to achieve is filtering of the objects
array so that I get an array of objects with unique actors.
So this is what I currently have:
var objects = [{
actor: {
account: null,
degraded: false,
mbox: null,
mbox_sha1sum: "843c56da78f9eb888274d2d4e12ab1d748ec46234",
name: "name",
openid: null
},
capture: 'value'
},
{
actor: {
account: null,
degraded: false,
mbox: null,
mbox_sha1sum: "843c56da78f9eb888274d2d4e12ab1d748ec12345",
name: "name2",
openid: null
},
capture: 'value2'
},
{
actor: {
account: null,
degraded: false,
mbox: null,
mbox_sha1sum: "843c56da78f9eb888274d2d4e12ab1d748ec46234",
name: "name",
openid: null
},
capture: 'value3'
}
];
objects.filter((value, index, self) => {
return self.indexOf(value) === index;
}).map(ele => {
console.log(ele.capture);
});
The desired outcome is an array which does not consist of the last array element as this actor property matches the first array element.
But as you can see, at the moment it does not filter any of the array elements.
At first I thought that return self.indexOf(value.value) === index;
would solve this issue, however this returns an empty array.
The expected result is:
[{
actor: {
account: null,
degraded: false,
mbox: null,
mbox_sha1sum: "843c56da78f9eb888274d2d4e12ab1d748ec46234",
name: "name",
openid: null
},
capture: 'value'
},
{
actor: {
account: null,
degraded: false,
mbox: null,
mbox_sha1sum: "843c56da78f9eb888274d2d4e12ab1d748ec12345",
name: "name2",
openid: null
},
capture: 'value2'
}
];
One way to get distinct values from an array of JavaScript objects is to use the array's map method to get an array with the values of a property in each object. Then we can remove the duplicate values with the Set constructor. And then we can convert the set back to an array with the spread operator.
One can use filter() function in JavaScript to filter the object array based on attributes. The filter() function will return a new array containing all the array elements that pass the given condition. If no elements pass the condition it returns an empty array.
JavaScript's Objects are not iterable like arrays or strings, so we can't make use of the filter() method directly on an Object . filter() allows us to iterate through an array and returns only the items of that array that fit certain criteria, into a new array.
The objects in your array are all different objects, even if some happen to have properties with the same values. The .indexOf()
function is comparing references, not property values.
Also, in practice, none of the three objects have identical properties because they all have a different .capture
value.
Use .findIndex()
instead of .indexOf()
, so that you can compare the properties to find matching objects:
objects.filter((value, index, self) => {
return self.findIndex(v => v.actor.name === value.actor.name) === index;
})
Here I'm just using the .actor.name
property, but of course you could compare additional properties if needed.
(Note that .findIndex()
is an ES6 function, but I assume that's fine given that your code is already using arrow functions. Or you can polyfill it.)
var objects = [{
actor: {
account: null,
degraded: false,
mbox: null,
mbox_sha1sum: "843c56da78f9eb888274d2d4e12ab1d748ec46234",
name: "name",
openid: null
},
capture: 'value'
},
{
actor: {
account: null,
degraded: false,
mbox: null,
mbox_sha1sum: "843c56da78f9eb888274d2d4e12ab1d748ec12345",
name: "name2",
openid: null
},
capture: 'value2'
},
{
actor: {
account: null,
degraded: false,
mbox: null,
mbox_sha1sum: "843c56da78f9eb888274d2d4e12ab1d748ec46234",
name: "name",
openid: null
},
capture: 'value3'
}
];
objects.filter((value, index, self) => {
return self.findIndex(v => v.actor.name === value.actor.name) === index;
}).map(ele => {
console.log(ele.capture);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With