假设我有一个对象:

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


当前回答

简单的方法!这样做。

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

其他回答

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

相反,使用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中简单用例的基准测试。不同浏览器的结果会有所不同。

我知道这个问题已经有很多答案了,这是一个相当老的问题。但我刚想出了一句简洁的俏皮话

JSON.parse(JSON.stringify(raw, ['key', 'value', 'item1', 'item3']))

这将返回另一个具有白名单属性的对象。注意,键和值包含在列表中。

你能找到的最干净的方法是使用Lodash#pick

const _ = require('lodash');

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

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

const filteredObj = _.pick(obj, allowed)

你现在可以使用Object.fromEntries方法(检查浏览器支持)使它更短更简单:

const raw = { item1: { prop:'1' }, item2: { prop:'2' }, item3: { prop:'3' } };

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

const filtered = Object.fromEntries(
   Object.entries(raw).filter(
      ([key, val])=>allowed.includes(key)
   )
);

阅读更多信息:Object.fromEntries

您可以添加一个通用的筛选器(使用通用的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中,但是你也可以轻松地从头开始编写它