Javascript 在ES6中按键筛选对象属性
假设我有一个对象:Javascript 在ES6中按键筛选对象属性,javascript,ecmascript-6,filter,Javascript,Ecmascript 6,Filter,假设我有一个对象: { 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'
{
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-raw={
项1:{键:'sdfd',值:'sdfd'},
项2:{键:'sdfd',值:'sdfd'},
项3:{键:'sdfd',值:'sdfd'}
};
允许的常量=['item1','item3'];
const filtered=Object.keys(原始)
.filter(键=>允许。包括(键))
.reduce((对象,键)=>{
obj[key]=原始[key];
返回obj;
}, {});
console.log(过滤)
您可以添加一个过滤器的通用(使用generic或reduce
实现),这样您就可以像过滤数组一样轻松地过滤对象——
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)=>
对象
.条目(o)
减少
((acc,[k,v])=>f(acc,v,k,o)
,acc
)
滤波器常数=(f,o)=>
减少
((acc、v、k、o)=>
f(v,k,o)
?Object.assign(acc,{[k]:v})
:acc
, {}
,o
)
常量数据=
{item1:{key:'a',value:1}
,item2:{key:'b',value:2}
,item3:{key:'c',value:3}
}
console.log
(过滤器的)
((v,k)=>k!=='item2'
,数据
)
//[{item1:{key:'a',value:1}
//,{item3:{key:'c',value:3}
// ]
,of filter
(x=>x.value==3
,数据
)
//[{item3:{key:'c',value:3}]
)
如果您不介意使用ES6语法,我发现最干净的方法是:
现在,newData
包含:
{
item1: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
};
或者,如果密钥存储为字符串:
const key = 'item2';
const { [key]: _, ...newData } = data;
在后一种情况下,[key]
转换为item2
,但由于您使用的是const
赋值,因此需要为赋值指定名称<代码>.
表示丢弃值
更一般地说:
const { item2, ...newData } = data; // Assign item2 to item2
const { item2: someVarName, ...newData } = data; // Assign item2 to someVarName
const { item2: _, ...newData } = data; // Assign item2 to _
const { ['item2']: _, ...newData } = data; // Convert string to key first, ...
这不仅可以将您的操作简化为一行,而且不需要您知道其他键(您希望保留的键)是什么
一个简单的实用程序函数如下所示:
function removePropFromObject(obj, prop) {
const { [prop]: _, ...rest } = obj
return { ...rest }
}
filteredObject(myData, ['item2']); //{item1: { key: 'sdfd', value:'sdfd' }, item3: { key: 'sdfd', value:'sdfd' }}
const base = {
item1: { key: 'sdfd', value:'sdfd' },
item2: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
};
const filtered = (
source => {
with(source){
return {item1, item3}
}
}
)(base);
// one line
const filtered = (source => { with(source){ return {item1, item3} } })(base);
我最近就是这样做的:
const dummyObj = Object.assign({}, obj);
delete dummyObj[key];
const target = Object.assign({}, {...dummyObj});
你能找到的最干净的方法就是
没有什么是以前没有说过的,但要将一些答案与ES6的一般答案结合起来:
const-raw={
项1:{键:'sdfd',值:'sdfd'},
项2:{键:'sdfd',值:'sdfd'},
项3:{键:'sdfd',值:'sdfd'}
};
常量filteredKeys=['item1','item3'];
const filteredKeys=filteredKeys
.reduce((obj,key)=>({…obj[key]:raw[key]}),{});
console.log(过滤)代码>背驮在上面
这是一个可重用的版本
Object.filterByKey = function (obj, predicate) {
return Object.keys(obj)
.filter(key => predicate(key))
.reduce((out, key) => {
out[key] = obj[key];
return out;
}, {});
}
称之为使用
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 arrow函数的美妙之处在于,您不必将allowed
作为参数传入。好的,这样如何:
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;
}
这样称呼它:
function removePropFromObject(obj, prop) {
const { [prop]: _, ...rest } = obj
return { ...rest }
}
filteredObject(myData, ['item2']); //{item1: { key: 'sdfd', value:'sdfd' }, item3: { key: 'sdfd', value:'sdfd' }}
const base = {
item1: { key: 'sdfd', value:'sdfd' },
item2: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
};
const filtered = (
source => {
with(source){
return {item1, item3}
}
}
)(base);
// one line
const filtered = (source => { with(source){ return {item1, item3} } })(base);
这只是现代JS的一行中的另一个解决方案,没有外部库
我在玩“解构”功能:
const-raw={
项1:{键:'sdfd',值:'sdfd'},
项2:{键:'sdfd',值:'sdfd'},
项3:{键:'sdfd',值:'sdfd'}
};
var myNewRaw=({item1,item3})=>({item1,item3}))(raw);
console.log(myNewRaw)代码>实现这一点的方法有很多。使用关键帧过滤器减少方法,这不是最有效的方法
相反,使用
for…in
循环遍历对象的键,或循环遍历允许的键,然后组合新对象的性能提高约50%
a。有关简单用例的基准,请参见。结果会因浏览器而异。这里的答案肯定是合适的,但速度有点慢,因为它们需要在对象中每个属性的白名单中循环。对于大型数据集,下面的解决方案要快得多,因为它只在白名单中循环一次:
const数据={
允许1:‘废话’,
允许2:‘废话’,
不允许:“哇,
超级敏感信息:“哇,
允许3:‘呜呜’
};
常量白名单=['allowed1','allowed2','allowed3'];
函数清理(数据、白名单){
返回白名单.reduce(
(结果,键)=>
数据[键]!==未定义
?Object.assign(结果,{[key]:数据[key]})
:结果,
{}
);
}
const result=sanitize(数据,白名单);
控制台日志(结果)代码>您可以执行以下操作:
function removePropFromObject(obj, prop) {
const { [prop]: _, ...rest } = obj
return { ...rest }
}
filteredObject(myData, ['item2']); //{item1: { key: 'sdfd', value:'sdfd' }, item3: { key: 'sdfd', value:'sdfd' }}
const base = {
item1: { key: 'sdfd', value:'sdfd' },
item2: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
};
const filtered = (
source => {
with(source){
return {item1, item3}
}
}
)(base);
// one line
const filtered = (source => { with(source){ return {item1, item3} } })(base);
这是可行的,但不是很清楚,另外不建议使用with
语句()。不使用过滤器的简单解决方案可以通过对象.entries()
而不是对象.keys()
此函数将根据键列表筛选对象,它比前面的答案更有效,因为它在调用reduce之前不必使用Array.filter。所以它的O(n)与O(n+过滤)
好的,这个班轮怎么样
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]})));
在循环过程中,遇到某些属性/键时不返回任何内容,并继续执行其余操作:
const loop = product =>
Object.keys(product).map(key => {
if (key === "_id" || key === "__v") {
return;
}
return (
<ul className="list-group">
<li>
{product[key]}
<span>
{key}
</span>
</li>
</ul>
);
});
const循环=产品=>
Object.keys(product.map)(key=>{
如果(键==“|id”|键==“|v”){
返回;
}
返回(
-
{产品[密钥]}
{key}
);
});
现在,您可以使用对象将其缩短并简化。fromEntries方法(检查浏览器支持):
阅读更多信息:您可以删除对象上的特殊属性
items={
item1: { key: 'sdfd', value:'sdfd' },
item2: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
}
// Example 1
var key = "item2";
delete items[key];
// Example 2
delete items["item2"];
// Example 3
delete items.item2;
简单的方法!这样做。
const myData={
项1:{键:'sdfd',值:'sdfd'
const filteredObject = Object.fromEntries(Object.entries(originalObject).filter(([key, value]) => key !== uuid))
const unfilteredObj = {a: ..., b:..., c:..., x:..., y:...}
const filterObject = ({a,b,c}) => ({a,b,c})
const filteredObject = filterObject(unfilteredObject)
const unfilteredObj = {a: ..., b:..., c:..., x:..., y:...}
const filteredObject = (({a,b,c})=>({a,b,c}))(unfilteredObject);
const raw = {
item1: { key: 'sdfd', value:'sdfd' },
item2: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
};
const allowed = ['item1', 'item3'];
const filtered = allowed.reduce((obj, key) => {
obj[key] = raw[key];
return obj
}, {})
console.log(filtered);
const object = Object.fromEntries(
Object.entries(raw).filter(([key, value]) => allowed.includes(key))
);
const filterObject = (obj, condition) => {
const filteredObj = {};
Object.keys(obj).map(key => {
if (condition(key)) {
dataFiltered[key] = obj[key];
}
});
return filteredObj;
}
JSON.parse(JSON.stringify(raw, ['key', 'value', 'item1', 'item3']))