假设我有一个对象:
{
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实现此目的的简洁方法,因此可以使用扩展运算符。 谢谢!
答案 0 :(得分:295)
如果您有允许值列表,则可以使用以下方法轻松地将它们保留在对象中:
const raw = {
item1: { key: 'sdfd', value:'sdfd' },
item2: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
};
const allowed = ['item1', 'item3'];
const filtered = Object.keys(raw)
.filter(key => allowed.includes(key))
.reduce((obj, key) => {
obj[key] = raw[key];
return obj;
}, {});
console.log(filtered);

这使用:
Object.keys
列出raw
中所有属性(原始数据),然后Array.prototype.filter
使用选择允许列表中存在的键
Array.prototype.includes
确保他们在场Array.prototype.reduce
构建一个只包含允许属性的新对象。这将使用允许的属性进行浅层复制(但不会自行复制属性)。
你也可以使用the object spread operator创建一系列对象而不会改变它们(感谢rjerue for mentioning this):
const raw = {
item1: { key: 'sdfd', value:'sdfd' },
item2: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
};
const allowed = ['item1', 'item3'];
const filtered = Object.keys(raw)
.filter(key => allowed.includes(key))
.reduce((obj, key) => {
return {
...obj,
[key]: raw[key]
};
}, {});
console.log(filtered);

出于琐事的目的,如果你想从原始数据中删除不需要的字段(我不会建议这样做,因为它涉及一些丑陋的突变),你可以反转{{1像这样检查:
includes

我包括这个例子来展示一个基于突变的解决方案,但我不建议使用它。
答案 1 :(得分:54)
如果您对使用ES6语法没问题,我发现最简洁的方法是执行此操作,如here和here所示:
const data = {
item1: { key: 'sdfd', value:'sdfd' },
item2: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
};
const { item2, ...newData } = data;
现在,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, ...
这不仅会减少您对单行的操作,而且还不需要您知道其他键是什么(您希望保留的那些键)。
答案 2 :(得分:31)
您可以找到最简洁的方法是使用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)
答案 3 :(得分:14)
之前没有说过什么,而是将一些答案与一般的ES6答案结合起来:
const raw = {
item1: { key: 'sdfd', value: 'sdfd' },
item2: { key: 'sdfd', value: 'sdfd' },
item3: { key: 'sdfd', value: 'sdfd' }
};
const filteredKeys = ['item1', 'item3'];
const filtered = filteredKeys
.reduce((obj, key) => ({ ...obj, [key]: raw[key] }), {});
console.log(filtered);
答案 4 :(得分:11)
一行代码中的另一种解决方案。
我正在玩" 解构"功能:
const raw = {
item1: { key: 'sdfd', value: 'sdfd' },
item2: { key: 'sdfd', value: 'sdfd' },
item3: { key: 'sdfd', value: 'sdfd' }
};
var myNewRaw = (({ item1, item3}) => ({ item1, item3 }))(raw);
console.log(myNewRaw);

答案 5 :(得分:6)
您可以添加通用ofilter
(使用通用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
,但您可以轻松地从头开始编写
答案 6 :(得分:5)
使用“新” Array.reduce
方法的另一种解决方案:
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);
Demonstration in this Fiddle...
但是我喜欢this answer here中使用Object.fromEntries
Array.filter
和Array.includes
的解决方案:
const object = Object.fromEntries( Object.entries(raw).filter(([key, value]) => allowed.includes(key)) );
答案 7 :(得分:4)
这就是我最近的做法:
const dummyObj = Object.assign({}, obj);
delete dummyObj[key];
const target = Object.assign({}, {...dummyObj});
答案 8 :(得分:3)
好吧,这种单线呢
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]})));
答案 9 :(得分:3)
这是一个可重复使用的版本。
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箭头功能的美妙之处在于,您不必将allowed
作为参数传递。
答案 10 :(得分:2)
这里的答案绝对合适,但它们有点慢,因为它们需要通过白名单循环访问对象中的每个属性。对于大型数据集,下面的解决方案要快得多,因为它只会循环通过白名单一次:
const data = {
allowed1: 'blah',
allowed2: 'blah blah',
notAllowed: 'woah',
superSensitiveInfo: 'whooooah',
allowed3: 'bleh'
};
const whitelist = ['allowed1', 'allowed2', 'allowed3'];
function sanitize(data, whitelist) {
return whitelist.reduce(
(result, key) =>
data[key] !== undefined
? Object.assign(result, { [key]: data[key] })
: result,
{}
);
}
sanitize(data, whitelist)
答案 11 :(得分:2)
上述许多解决方案对Array.prototype.includes
中的每个键重复调用raw
,这将使解决方案O(n·m)(其中n是对象中的键数,m是允许列表的长度)。
这可以通过使用允许的 Set 来避免,但是迭代 allowed
键并将它们复制到初始为空的对象中会得到非常简单、可读的代码,即 O(m):
const raw = {
item1: { key: 'sdfd', value:'sdfd' },
item2: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
};
const allowed = ['item1', 'item3'];
const filtered = {};
for (const key of allowed) {
if (key in raw) filtered[key] = raw[key];
}
console.log(filtered);
如果您想避免复制继承的属性,也可以使用 raw.hasOwnProperty(key)
代替 key in raw
。
答案 12 :(得分:2)
我很惊讶没有人提出这个建议。非常干净,而且非常明确地表明您要保留哪些密钥。
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);
答案 13 :(得分:2)
const filteredObject = Object.fromEntries(Object.entries(originalObject).filter(([key, value]) => key !== uuid))
答案 14 :(得分:2)
可以使用filter
代替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
},{})
答案 15 :(得分:2)
您可以执行以下操作:
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
语句(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with)。
答案 16 :(得分:1)
您可以删除对象上的特殊键
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;
答案 17 :(得分:1)
简单方法!为此。
const myData = {
item1: { key: 'sdfd', value:'sdfd' },
item2: { key: 'sdfd', value:'sdfd' },
item3: { key: 'sdfd', value:'sdfd' }
};
const{item1,item3}=myData
const result =({item1,item3})
答案 18 :(得分:1)
另一种简便方法
function filterByKey(v,keys){
const newObj ={};
keys.forEach(key=>{v[key]?newObj[key]=v[key]:''});
return newObj;
}
//given
let obj ={ foo: "bar", baz: 42,baz2:"blabla" , "spider":"man", monkey:true};
//when
let outObj =filterByKey(obj,["bar","baz2","monkey"]);
//then
console.log(outObj);
//{
// "baz2": "blabla",
// "monkey": true
//}
答案 19 :(得分:1)
我知道这已经有很多答案了 是一个相当老的问题。但是我只是想出了这种简洁的单线纸:
JSON.parse(JSON.stringify(raw, ['key', 'value', 'item1', 'item3']))
这将返回另一个仅具有白名单属性的对象。请注意,列表中包含key
和value
。
答案 20 :(得分:0)
好的,:这是怎么回事:
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' }}
答案 21 :(得分:0)
在循环期间,遇到某些属性/键时不返回任何内容,然后继续进行其余操作:
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>
);
});
答案 22 :(得分:0)
您现在可以使用 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
答案 23 :(得分:0)
此函数将根据键列表过滤对象,它比以前的答案更有效,因为在调用reduce之前不必使用Array.filter。因此它的O(n)不同于O(n +已过滤)
function filterObjectByKeys (object, keys) {
return Object.keys(object).reduce((accum, key) => {
if (keys.includes(key)) {
return { ...accum, [key]: object[key] }
} else {
return accum
}
}, {})
}
答案 24 :(得分:0)
另一种方法是将Array.prototype.forEach()
用作
const raw = {
item1: {
key: 'sdfd',
value: 'sdfd'
},
item2: {
key: 'sdfd',
value: 'sdfd'
},
item3: {
key: 'sdfd',
value: 'sdfd'
}
};
const allowed = ['item1', 'item3', 'lll'];
var finalObj = {};
allowed.forEach(allowedVal => {
if (raw[allowedVal])
finalObj[allowedVal] = raw[allowedVal]
})
console.log(finalObj)
它仅包含原始数据中可用的那些键的值,从而防止添加任何垃圾数据。
答案 25 :(得分:0)
那是我的解决办法:
const filterObject = (obj, condition) => {
const filteredObj = {};
Object.keys(obj).map(key => {
if (condition(key)) {
dataFiltered[key] = obj[key];
}
});
return filteredObj;
}
答案 26 :(得分:0)
以下方法将对象和所有属性过滤掉。
function removeObjectKeys(obj, ...keysToRemove) {
let mObject = { ...obj }
for (let key of keysToRemove) {
const { [String(key)]: _, ...rest } = mObject
mObject = { ...rest }
}
return mObject
}
const obj = { 123: "hello", 345: "world", 567: "and kitty" };
const filtered = removeObjectKeys(obj, 123);
console.log(filtered);
const twoFiltered = removeObjectKeys(obj, 345, 567);
console.log(twoFiltered);
答案 27 :(得分:0)
使用 PropPick 包
pick('item1 item3', obj);
// {
// item1: { key: 'sdfd', value:'sdfd' },
// item3: { key: 'sdfd', value:'sdfd' }
// }
答案 28 :(得分:0)
有很多方法可以实现这一目标。 accepted answer使用Keys-Filter-Reduce方法,这种方法效果不是最好的。
相反,使用for...in
循环来循环访问对象的键,或循环通过允许的键,然后组成一个新对象的性能提高约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
一个。有关简单用例的基准,请参阅jsPerf。结果将根据浏览器而有所不同。