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对象的字段之一。