admin管理员组文章数量:1287150
I know there's many ways to filter arrays for unique values, but what about filtering arrays for objects with unique values for a given field?
For example I have [obj1, obj2, obj3, ...]
where each object is of the following form:
{
firstName: "...",
lastName: "..."
}
How can I filter the array to end up with a final array where all the objects have unique first names? A one-liner would be better, though not at the cost of readability.
I know there's many ways to filter arrays for unique values, but what about filtering arrays for objects with unique values for a given field?
For example I have [obj1, obj2, obj3, ...]
where each object is of the following form:
{
firstName: "...",
lastName: "..."
}
How can I filter the array to end up with a final array where all the objects have unique first names? A one-liner would be better, though not at the cost of readability.
Share Improve this question asked Jul 16, 2017 at 3:52 frozenfrozen 2,13816 silver badges33 bronze badges 1-
From torazaburo's answer, the 1-liner is :
arr.filter((e, i) => arr.findIndex(e2 => e.firstName === e2.firstName) === i)
– frozen Commented Jul 23, 2017 at 13:00
6 Answers
Reset to default 9Filter in only those items which are not found earlier in the array. We'll define cond
as returning whether two items should be considered "equal".
function uniqueBy(a, cond) {
return a.filter((e, i) => a.findIndex(e2 => cond(e, e2)) === i);
}
const test = [
{ firstname: "John", lastname: "Doe" },
{ firstname: "Jane", lastname: "Doe" },
{ firstname: "John", lastname: "Smith" }
];
console.log(uniqueBy(test, (o1, o2) => o1.firstname === o2.firstname));
You can reduce the array into a Map, and then spread the map values back to an array.
If you want to keep the 1st objects encountered, you have to check if the map already has the firstName
as key, and set only if it doesn't exist yet.
const arr = [{"firstname":"Robert","lastname":"Smith"},{"firstname":"Francis","lastname":"Collins"},{"firstname":"Robert","lastname":"Ludlum"},{"firstname":"Francis","lastname":"bacon"}];
const result = [...arr.reduce((map, obj) => map.has(obj.firstname) ? map : map.set(obj.firstname, obj), new Map()).values()];
console.log(result);
If you want to keep the last objects, you can skip the check, and just set them:
const arr = [{"firstname":"Robert","lastname":"Smith"},{"firstname":"Francis","lastname":"Collins"},{"firstname":"Robert","lastname":"Ludlum"},{"firstname":"Francis","lastname":"bacon"}];
const result = [...arr.reduce((map, obj) => map.set(obj.firstname, obj), new Map()).values()];
console.log(result);
You can use reduce method, and set initial value to be an array, push object to the new array conditionally i.e. if first name doesn't already exist:
var arr = [ { firstname: "John",
lastname: "Doe" },
{ firstname: "Jane",
lastname: "Doe" },
{ firstname: "John",
lastname: "Doe" }];
console.log(
arr.reduce(
function(unique_arr, obj) {
if(!unique_arr.some(x => x.firstname === obj.firstname)) {
unique_arr.push(obj)
}
return unique_arr;
}, [])
);
The answers seem intent on checking if your result array has the value, but for uniqueness I find it easier and more manageable to use an object and always set the value, without needing to check for it. This relies on the premise that objects may only have unique keys:
var arr = [{
firstName: "Amy",
lastName: "Adams"
},
{
firstName: "Bryan",
lastName: "Heart"
},
{
firstName: "Amy",
lastName: "Adams"
}
];
var unique = {};
for (var i = 0, n = arr.length; i < n; i++) {
// Key is your unique condition
var key = [arr[i].firstName, arr[i].lastName].join(' ');
unique[key] = arr[i];
}
console.log('Keys:', Object.keys(unique)); // only shown for austerity
console.log('Values:', Object.values(unique));
How about a 2-liner.
var ar = [{firstName: 'Jo'}, {firstName: 'Bill'}, {firstName: 'Bill'}];
var firstNames = [];
var uniqueFirstName = ar.filter(obj =>
firstNames.indexOf(obj.firstName) > -1
? false : firstNames.push(obj.firstName))
console.log( JSON.stringify(uniqueFirstName));
I would filter and keep a Set of thr firstnames that already appeared:
const names = new Set();
const result = array.filter(({ firstName }) => !names.has(firstName) && names.add(firstName));
本文标签: javascriptFilter array for unique field valuesStack Overflow
版权声明:本文标题:javascript - Filter array for unique field values - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741307186a2371438.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论