在 ES6 中按键筛选对象属性

2022-08-29 23:15:29

假设我有一个对象:

{
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
}

我想通过过滤上面的对象来创建另一个对象,所以我有类似的东西。

 {
    item1: { key: 'sdfd', value:'sdfd' },
    item3: { key: 'sdfd', value:'sdfd' }
 }

我正在寻找一种使用Es6实现此目的的干净方法,因此我可以使用传播运算符。


答案 1

如果您有允许值的列表,则可以使用以下方法轻松地将它们保留在对象中:

const raw = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const allowed = ['item1', 'item3'];

const filtered = Object.keys(raw)
  .filter(key => allowed.includes(key))
  .reduce((obj, key) => {
    obj[key] = raw[key];
    return obj;
  }, {});

console.log(filtered);

这使用:

  1. Object.keys 列出(原始数据)中的所有属性,然后raw
  2. Array.prototype.filter 选择允许列表中存在的键,使用
    1. Array.prototype.include 以确保它们存在
  3. Array.prototype.reduce 以仅使用允许的属性构建新对象。

这将使用允许的属性创建浅层复制(但不会复制属性本身)。

您还可以使用对象展开运算符来创建一系列对象,而不会改变它们(感谢 rjerue 提到这一点):

const raw = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const allowed = ['item1', 'item3'];

const filtered = Object.keys(raw)
  .filter(key => allowed.includes(key))
  .reduce((obj, key) => {
    return {
      ...obj,
      [key]: raw[key]
    };
  }, {});

console.log(filtered);

出于琐事的目的,如果您想从原始数据中删除不需要的字段(我不建议这样做,因为它涉及一些丑陋的突变),您可以像这样反转检查:includes

const raw = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const allowed = ['item1', 'item3'];

Object.keys(raw)
  .filter(key => !allowed.includes(key))
  .forEach(key => delete raw[key]);

console.log(raw);

我包含此示例是为了展示基于突变的解决方案,但我不建议使用它。


答案 2

如果您可以使用ES6语法,我发现最干净的方法可以做到这一点,如这里这里所述:

const data = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const { item2, ...newData } = data;

现在,包含:newData

{
  item1: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

或者,如果您将密钥存储为字符串:

const key = 'item2';
const { [key]: _, ...newData } = data;

在后一种情况下,将转换为,但由于您使用的是赋值,因此需要为赋值指定一个名称。 表示丢弃值。[key]item2const_

更一般地说:

const { item2, ...newData } = data; // Assign item2 to item2
const { item2: someVarName, ...newData } = data; // Assign item2 to someVarName
const { item2: _, ...newData } = data; // Assign item2 to _
const { ['item2']: _, ...newData } = data; // Convert string to key first, ...

这不仅将您的操作减少到单行,而且还不需要您知道其他密钥是什么(您要保留的密钥)。

一个简单的实用程序函数将如下所示:

function removePropFromObject(obj, prop) {
  const { [prop]: _, ...rest } = obj
  return { ...rest }
}