ES6 按唯一属性过滤对象
ES6 Filtering objects by unique attribute
我有一组错误,每个错误都有一个非唯一的 param
属性。
我想根据 param
之前是否看过来过滤数组。
像这样:
const filteredErrors = [];
let params = [];
for(let x = 0; x < errors.length; x++) {
if(!params.includes(errors[x].param)) {
params.push(errors[x].param);
filteredErrors.push(errors[x]);
}
}
但我不知道如何在 ES6 中做到这一点。
我可以得到唯一的参数const filteredParams = Array.from(new Set(errors.map(error => error.param)));
但不能得到对象本身。
很确定这只是我对高阶函数理解的弱点,但我就是无法理解它
您可以解构 param
,检查 params
并将值添加到参数和 return true
以获取对象作为过滤结果。
因此,您会得到一组首次发现的相同类型的错误。
const
params = [],
filteredErrors = errors.filter(({ param }) =>
!params.includes(param) && params.push(param));
我可能会用 reduce
这样做,不需要外部参数:
const filteredErrors = Object.values(
errors.reduce((acc, val) => {
if (!acc[val.param]) {
acc[val.param] = val;
}
return acc;
}, {}))
基本上将它转换成一个由参数键入的对象,以对象作为值,只有在之前没有设置过键的情况下才设置键,然后返回值数组。
像这样概括
function uniqueBy(array, prop) {
return Object.values(
array.reduce((acc, val) => {
if (!acc[val[prop]]) {
acc[val[prop]] = val;
}
return acc;
}, {}))
}
然后就这样做:
const filteredErrors = uniqueBy(errors, 'param');
您可以使用 Array.prototype.reduce
来完成。您需要遍历数组中的对象并将找到的 params
保留在 Set
中(如果它不存在)。
Set.prototype.has
会让你找到答案。如果 Set
中不存在,则将其添加到 Set
实例和最终累积数组中,以便在下一次迭代中,如果 param
存在于 [=13] 中=] 你不包括那个对象:
const errors = [{param: 1, val: "err1"}, {param: 2, val: "err2"}, {param: 3, val: "err3"}, {param: 2, val: "err4"}, {param: 1, val: "err5"}];
const { filteredParams } = errors.reduce((acc, e) => {
!acc.foundParams.has(e.param) && (acc.foundParams.add(e.param) &&
acc.filteredParams.push(e));
return acc;
}, {foundParams: new Set(), filteredParams: []});
console.log(filteredParams);
您可以使用对象来代替数组来保留现有值的映射并使用过滤功能
let params = {};
const filteredErrors = errors.filter(error => {
if(params[error.param]) return false;
params[error.param] = true;
return true;
});
如果你的参数有一个标志标识符,如果这个参数以前见过,那么你可以简单地这样做。
const filteredErrors = errors.filter(({ param }) => param.seen === true);
或
const filteredErrors = errors.filter((error) => error.param.seen);
errors 应该是一个对象数组。
其中param是array errors元素的字段之一,seen是param对象的字段之一。
我有一组错误,每个错误都有一个非唯一的 param
属性。
我想根据 param
之前是否看过来过滤数组。
像这样:
const filteredErrors = [];
let params = [];
for(let x = 0; x < errors.length; x++) {
if(!params.includes(errors[x].param)) {
params.push(errors[x].param);
filteredErrors.push(errors[x]);
}
}
但我不知道如何在 ES6 中做到这一点。
我可以得到唯一的参数const filteredParams = Array.from(new Set(errors.map(error => error.param)));
但不能得到对象本身。
很确定这只是我对高阶函数理解的弱点,但我就是无法理解它
您可以解构 param
,检查 params
并将值添加到参数和 return true
以获取对象作为过滤结果。
因此,您会得到一组首次发现的相同类型的错误。
const
params = [],
filteredErrors = errors.filter(({ param }) =>
!params.includes(param) && params.push(param));
我可能会用 reduce
这样做,不需要外部参数:
const filteredErrors = Object.values(
errors.reduce((acc, val) => {
if (!acc[val.param]) {
acc[val.param] = val;
}
return acc;
}, {}))
基本上将它转换成一个由参数键入的对象,以对象作为值,只有在之前没有设置过键的情况下才设置键,然后返回值数组。
像这样概括
function uniqueBy(array, prop) {
return Object.values(
array.reduce((acc, val) => {
if (!acc[val[prop]]) {
acc[val[prop]] = val;
}
return acc;
}, {}))
}
然后就这样做:
const filteredErrors = uniqueBy(errors, 'param');
您可以使用 Array.prototype.reduce
来完成。您需要遍历数组中的对象并将找到的 params
保留在 Set
中(如果它不存在)。
Set.prototype.has
会让你找到答案。如果 Set
中不存在,则将其添加到 Set
实例和最终累积数组中,以便在下一次迭代中,如果 param
存在于 [=13] 中=] 你不包括那个对象:
const errors = [{param: 1, val: "err1"}, {param: 2, val: "err2"}, {param: 3, val: "err3"}, {param: 2, val: "err4"}, {param: 1, val: "err5"}];
const { filteredParams } = errors.reduce((acc, e) => {
!acc.foundParams.has(e.param) && (acc.foundParams.add(e.param) &&
acc.filteredParams.push(e));
return acc;
}, {foundParams: new Set(), filteredParams: []});
console.log(filteredParams);
您可以使用对象来代替数组来保留现有值的映射并使用过滤功能
let params = {};
const filteredErrors = errors.filter(error => {
if(params[error.param]) return false;
params[error.param] = true;
return true;
});
如果你的参数有一个标志标识符,如果这个参数以前见过,那么你可以简单地这样做。
const filteredErrors = errors.filter(({ param }) => param.seen === true);
或
const filteredErrors = errors.filter((error) => error.param.seen);
errors 应该是一个对象数组。
其中param是array errors元素的字段之一,seen是param对象的字段之一。