假设我有一个对象:

{
  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,所以扩散操作符是可用的。


当前回答

如果你可以使用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]被转换为item2,但由于您使用的是const赋值,因此需要为赋值指定一个名称。_表示丢弃值。

更普遍的:

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 }
}

其他回答

另一种使用数组的解决方案。在允许的键上减少方法:

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

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

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

console.log(filtered);

特别是对于较大的源对象(在本例中为原始对象),这是有意义的。迭代不会使用源的所有条目执行,而只使用您想要过滤的键,因此更短/更快…

演示在这小提琴…


但我必须说,我也喜欢这个答案中的解决方案使用object。fromentries数组。filter和Array.includes:

const object = object . fromentries ( Object.entries(生)。Filter (([key, value]) => allowed.includes(key)) );

演示在这小提琴…

如果你有一个允许值的列表,你可以很容易地将它们保留在一个对象中:

Const raw = { Item1: {key: 'sdfd', value:'sdfd'}, Item2: {key: 'sdfd', value:'sdfd'}, Item3:{键:'sdfd',值:'sdfd'} }; Const allowed = ['item1', 'item3']; const filtered = Object.keys(raw) .filter(key => allowed.includes(key)) .reduce((obj, key) => { Obj [key] = raw[key]; 返回obj; }, {}); console.log(过滤);

这个用途:

对象。键来列出原始(原始数据)中的所有属性 Array.prototype.filter选择允许列表中出现的键,使用 Array.prototype.includes以确保它们存在 reduce构建一个只包含允许属性的新对象。

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

你也可以使用对象扩展操作符来创建一系列对象而不改变它们(感谢rjerue提到了这一点):

Const raw = { Item1: {key: 'sdfd', value:'sdfd'}, Item2: {key: 'sdfd', value:'sdfd'}, Item3:{键:'sdfd',值:'sdfd'} }; Const allowed = ['item1', 'item3']; const filtered = Object.keys(raw) .filter(key => allowed.includes(key)) .reduce((obj, key) => { 返回{ obj, (例子):生(例子) }; }, {}); console.log(过滤);

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

Const raw = { Item1: {key: 'sdfd', value:'sdfd'}, Item2: {key: 'sdfd', value:'sdfd'}, Item3:{键:'sdfd',值:'sdfd'} }; Const allowed = ['item1', 'item3']; 种(生) .filter(key => !allowed.includes(key)) .forEach(key => delete raw[key]); console.log(生);

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

另一种方法是使用Array.prototype.forEach()作为

Const raw = { item1: { 关键:“sdfd”, 价值:“sdfd” }, 第二条:{ 关键:“sdfd”, 价值:“sdfd” }, item3: { 关键:“sdfd”, 价值:“sdfd” } }; Const allowed = ['item1', 'item3', 'll ']; var finalObj = {}; 允许的。forEach(allowedVal => { 如果原始[allowedVal]) finalObj[allowedVal] = raw[allowedVal] }) console.log (finalObj)

它只包含原始数据中可用的那些键的值,从而防止添加任何垃圾数据。

有很多方法可以做到这一点。公认的答案使用键-过滤-减少方法,这不是最有效的。

相反,使用for…循环遍历一个对象的键,或者遍历允许的键,然后组合一个新对象的性能提高了50%。

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

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

function keysReduce (obj, keys) {
  return keys.reduce((acc, key) => {
    if(obj[key] !== undefined) {
      acc[key] = obj[key];
    }
    return acc;
  }, {});
};

function forInCompose (obj, keys) {
  const returnObj = {};
  for (const key in obj) {
    if(keys.includes(key)) {
      returnObj[key] = obj[key]
    }
  };
  return returnObj;
};

keysReduce(obj, keys);   // Faster if the list of allowed keys are short
forInCompose(obj, keys); // Faster if the number of object properties are low

a.查看jsPerf中简单用例的基准测试。不同浏览器的结果会有所不同。

这个函数将根据键列表筛选对象,它比前面的答案更有效,因为它不需要使用Array。在调用reduce之前进行筛选。所以它是O(n)而不是O(n +过滤)

function filterObjectByKeys (object, keys) {
  return Object.keys(object).reduce((accum, key) => {
    if (keys.includes(key)) {
      return { ...accum, [key]: object[key] }
    } else {
      return accum
    }
  }, {})
}