假设我有一个对象:
{
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
好吧,这样怎么样:
const myData = {
item1: { key: 'sdfd', value:'sdfd' },
item2: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
};
function filteredObject(obj, filter) {
if(!Array.isArray(filter)) {
filter = [filter.toString()];
}
const newObj = {};
for(i in obj) {
if(!filter.includes(i)) {
newObj[i] = obj[i];
}
}
return newObj;
}
像这样叫它:
filteredObject(myData, ['item2']); //{item1: { key: 'sdfd', value:'sdfd' }, item3: { key: 'sdfd', value:'sdfd' }}
利用ssube的答案。
这是一个可重用的版本。
Object.filterByKey = function (obj, predicate) {
return Object.keys(obj)
.filter(key => predicate(key))
.reduce((out, key) => {
out[key] = obj[key];
return out;
}, {});
}
叫它use
const raw = {
item1: { key: 'sdfd', value:'sdfd' },
item2: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
};
const allowed = ['item1', 'item3'];
var filtered = Object.filterByKey(raw, key =>
return allowed.includes(key));
});
console.log(filtered);
ES6箭头函数的美妙之处在于,你不必将allowed作为参数传入。
上面的许多解决方案都重复调用Array.prototype.includes来处理raw中的每个键,这将使解决方案为O(n·m)(其中n是对象中键的数量,m是允许列表的长度)。
这可以通过使用一个允许的Set来避免,但是遍历允许的键并将它们复制到一个初始为空的对象中会得到非常简单,可读的代码,即O(m):
Const raw = {
Item1: {key: 'sdfd', value:'sdfd'},
Item2: {key: 'sdfd', value:'sdfd'},
Item3:{键:'sdfd',值:'sdfd'}
};
Const allowed = ['item1', 'item3'];
Const filtered = {};
For(允许的const键){
If (key in raw) filter [key] = raw[key];
}
console.log(过滤);
如果你想避免复制继承的属性,你也可以使用raw. hasownproperty (key)来代替key in raw。