假设我有一个对象:
{
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,所以扩散操作符是可用的。
有很多方法可以做到这一点。公认的答案使用键-过滤-减少方法,这不是最有效的。
相反,使用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中简单用例的基准测试。不同浏览器的结果会有所不同。
一个不使用过滤器的更简单的解决方案可以通过Object.entries()而不是Object.keys()实现。
const raw = {
item1: { key: 'sdfd', value:'sdfd' },
item2: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
};
const allowed = ['item1', 'item3'];
const filtered = Object.entries(raw).reduce((acc,elm)=>{
const [k,v] = elm
if (allowed.includes(k)) {
acc[k] = v
}
return acc
},{})
好吧,这样怎么样:
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' }}
另一种方法是使用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 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(生);
我使用这个示例是为了展示一个基于突变的解决方案,但我不建议使用它。
好吧,这一行怎么样
const raw = {
item1: { key: 'sdfd', value: 'sdfd' },
item2: { key: 'sdfd', value: 'sdfd' },
item3: { key: 'sdfd', value: 'sdfd' }
};
const filteredKeys = ['item1', 'item3'];
const filtered = Object.assign({}, ...filteredKeys.map(key=> ({[key]:raw[key]})));