假设我有一个对象:

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


当前回答

基于以下两个答案:

https://stackoverflow.com/a/56081419/13819049 https://stackoverflow.com/a/54976713/13819049

我们可以:

const original = { a: 1, b: 2, c: 3 };
const allowed = ['a', 'b'];

const filtered = Object.fromEntries(allowed.map(k => [k, original[k]]));

哪个更干净更快:

https://jsbench.me/swkv2cbgkd/1

其他回答

这个函数将根据键列表筛选对象,它比前面的答案更有效,因为它不需要使用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
    }
  }, {})
}

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

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)

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

简单的方法!这样做。

const myData = { Item1: {key: 'sdfd', value:'sdfd'}, Item2: {key: 'sdfd', value:'sdfd'}, Item3:{键:'sdfd',值:'sdfd'} }; const {item1, item3} = myData Const result =({item1,item3})

您可以添加一个通用的筛选器(使用通用的oreduce实现),这样就可以像数组一样轻松地筛选对象

const oreduce = (f, acc, o) =>
  Object
    .entries (o)
    .reduce
      ( (acc, [ k, v ]) => f (acc, v, k, o)
      , acc
      )

const ofilter = (f, o) =>
  oreduce
    ( (acc, v, k, o)=>
        f (v, k, o)
          ? Object.assign (acc, {[k]: v})
          : acc
    , {}
    , o
    )

我们可以看到它在这里工作

const data =
  { item1: { key: 'a', value: 1 }
  , item2: { key: 'b', value: 2 }
  , item3: { key: 'c', value: 3 }
  }

console.log
  ( ofilter
      ( (v, k) => k !== 'item2'
      , data
      )
      // [ { item1: { key: 'a', value: 1 } }
      // , { item3: { key: 'c', value: 3 } }
      // ]

  , ofilter
      ( x => x.value === 3
      , data
      )
      // [ { item3: { key: 'c', value: 3 } } ]
  )

在您自己的浏览器中验证下面的结果

const oreduce = (f, acc, o) => Object .entries (o) .reduce ( (acc, [ k, v ]) => f (acc, v, k, o) , acc ) const ofilter = (f, o) => oreduce ( (acc, v, k, o)=> f (v, k, o) ? Object.assign (acc, { [k]: v }) : acc , {} , o ) const data = { item1: { key: 'a', value: 1 } , item2: { key: 'b', value: 2 } , item3: { key: 'c', value: 3 } } console.log ( ofilter ( (v, k) => k !== 'item2' , data ) // [ { item1: { key: 'a', value: 1 } } // , { item3: { key: 'c', value: 3 } } // ] , ofilter ( x => x.value === 3 , data ) // [ { item3: { key: 'c', value: 3 } } ] )

这两个功能可以通过多种方式实现。我选择将它附加到Array.prototype.reduce中的oreduce中,但是你也可以轻松地从头开始编写它