如何在 ES6 中使用其值过滤对象
Posted
技术标签:
【中文标题】如何在 ES6 中使用其值过滤对象【英文标题】:How to filter an object with its values in ES6 【发布时间】:2017-10-16 23:35:26 【问题描述】:在 ES6 中以这种方式过滤对象的最佳方法是什么?
起始数据:
const acceptedValues = ["value1","value3"]
const myObject =
prop1:"value1",
prop2:"value2",
prop3:"value3"
预期输出:
filteredObject =
prop1:"value1",
prop3:"value3"
【问题讨论】:
最好的方法是什么?一个简单的对象属性循环就可以了。 如果可能,尝试捕获已接受的键而不是值以简化此操作。 主要是在效率方面。一个简单的循环确实可以解决问题,但是 ES6 和“现代”数组方法可以使它更容易。 .reduce() 的答案就是 imo 的一个很好的例子。 最好的方法?不要从一开始就使用Object
(而是Array
)。
【参考方案1】:
对于 ES6,如果您需要静态代码(您确切知道需要过滤哪些属性)并且它不依赖于应用程序状态,那么您可以使用以下解构技术:
const myObject =
prop1: 'value1',
prop2: 'value2',
prop3: 'value3'
const prop2, ...filteredObject = myObject
console.info( filteredObject, prop2 )
你将拥有:
filteredObject: prop1: "value1", prop3: "value3"
prop2: "value2"
【讨论】:
【参考方案2】:因为我还没有看到使用Object.entries
的答案,所以这里有一个。请注意,由于Object.entries()
的实现比Object.keys()
慢得多,这也将比接受的答案慢,但有些人可能更喜欢这样的可读性或可扩展性(更容易通过不同的过滤函数)。
const acceptedValues = ["value1", "value3"];
const myObject =
prop1:"value1",
prop2:"value2",
prop3:"value3"
;
const filteredEntries = Object.entries(myObject).filter(([, v]) => acceptedValues.includes(v));
const filteredObject = Object.fromEntries(filteredEntries);
或者作为一个较长的单线:
const filteredObject = Object.fromEntries(Object.entries(myObject).filter(([, v]) => accepted.includes(v)));
【讨论】:
【参考方案3】:IMO,“最好的方式”是 Lodash 方式
const filtered = _.pick(myObject, acceptedValues)
https://lodash.com/docs/4.17.10#pick
【讨论】:
刚刚看了你的一个视频 .. fireship 太棒了!【参考方案4】:只是在@Nenad Vracar 的基础上构建良好的答案,您可以使用对象而不是带有includes
的数组来加快查找速度:
const acceptedValues = ["value1", "value3"];
const myObject =
prop1: "value1",
prop2: "value2",
prop3: "value3"
;
const lookup = acceptedValues.reduce( (memo, prop) =>
memo[prop] = true;
return memo;
);
const filteredObject = Object.keys(myObject).reduce((filtered, key) =>
if(lookup[myObject[key]])
filtered[key] = myObject[key];
return filtered;
, );
console.log(filteredObject);
includes
也不能胜任这项工作,但我想提供另一种观点。
【讨论】:
【参考方案5】:function filter(myObject)
var obj=Object.assign(,myObject);
Object.keys(obj).forEach(function(key)
if(acceptedValues.indexOf(obj[key])<0) delete obj[key];
);
return obj;
const filteredObject=filter(myObject);
【讨论】:
【参考方案6】:使用简单的 for 循环并按键获取对象。
const acceptedValues = ["value1","value3"]
const myObject =
prop1:"value1",
prop2:"value2",
prop3:"value3"
Object.prototype.getKeyByValue = function( value )
for( var prop in this )
if( this.hasOwnProperty( prop ) )
if( this[ prop ] === value )
return prop;
for (var i in acceptedValues)
if (myObject.getKeyByValue(acceptedValues[i]))
console.log(acceptedValues[i]);
【讨论】:
【参考方案7】:为什么不是一个简单的 for 循环?
const acceptedValues = ["value1","value3"]
const myObject =
prop1:"value1",
prop2:"value2",
prop3:"value3"
;
var filteredObject = ;
for(e in myObject)
if (myObject.hasOwnProperty(e))
if (acceptedValues.indexOf(myObject[e]) != -1)
filteredObject[e] = myObject[e];
console.log(filteredObject);
【讨论】:
【参考方案8】:您可以使用reduce()
创建新对象,使用includes()
检查对象的值是否存在于数组中。
const acceptedValues = ["value1", "value3"]
const myObject =
prop1: "value1",
prop2: "value2",
prop3: "value3"
var filteredObject = Object.keys(myObject).reduce(function(r, e)
if (acceptedValues.includes(myObject[e])) r[e] = myObject[e]
return r;
, )
console.log(filteredObject)
【讨论】:
您能否解释一下为什么当我有对象时在这种情况下使用.filter
不起作用? this.activeUsers = window.users.filter( function(user) // return ( (user.test === '0') && (user.isok === '0') ); return user.user_id === 1; );
收到错误 .filter is not a function
@W.Doch 因为过滤器不适用于对象,仅适用于数组以上是关于如何在 ES6 中使用其值过滤对象的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Javascript/Lodash/ES6 中同时搜索父对象和子对象?