[英]How do I find objects with a property inside another object in JavaScript
I have a object with all my users, like so: var users = {user1:{}, user2:{}}
, And every user has a isPlaying property.我的所有用户都有一个对象,如下所示: var users = {user1:{}, user2:{}}
,每个用户都有一个 isPlaying 属性。 How do I get all users that have isPlaying false?我如何让所有拥有 isPlaying 的用户都是假的?
You should use Object.keys
, Array.prototype.filter
and Array.prototype.map
:您应该使用Object.keys
、 Array.prototype.filter
和Array.prototype.map
:
// This will turn users object properties into a string array
// of user names
var userNames = Object.keys(users);
// #1 You need to filter which users aren't playing. So, you
// filter accessing users object by user name and you check that
// user.isPlaying is false
//
// #2 Using Array.prototype.map, you turn user names into user objects
// by projecting each user name into the user object!
var usersNotPlaying = userNames.filter(function(userName) {
return !users[userName].isPlaying;
}).map(function(userName) {
return users[userName];
});
If it would be done using ECMA-Script 6, you could do using arrow functions:如果使用 ECMA-Script 6 完成,您可以使用箭头函数:
// Compact and nicer!
var usersNotPlaying = Object.keys(users)
.filter(userName => users[userName].isPlaying)
.map(userName => users[userName]);
Array.prototype.reduce
使用Array.prototype.reduce
As @RobG has pointed out, you can also use Array.prototype.reduce
.正如@RobG 所指出的,您也可以使用Array.prototype.reduce
。
While I don't want to overlap his new and own answer, I believe that reduce
approach is more practical if it returns an array of user objects not playing .虽然我不想重叠他的新答案和自己的答案,但我相信如果reduce
方法返回一组用户对象not play则更实用。
Basically, if you return an object instead of an array, the issue is that another caller (ie a function which calls the one doing the so-called reduce
) may need to call reduce
again to perform a new operation, while an array is already prepared to fluently call other Array.prototype
functions like map
, filter
, forEach
...基本上,如果您返回一个对象而不是数组,问题是另一个调用者(即调用执行所谓的reduce
的函数的函数)可能需要再次调用reduce
来执行新操作,而数组已经是准备流畅地调用其他Array.prototype
函数,如map
、 filter
、 forEach
...
The code would look this way:代码看起来像这样:
// #1 We turn user properties into an array of property names
// #2 Then we call "reduce" on the user property name array. Reduce
// takes a callback that will be called for every array item and it receives
// the array reference given as second parameter of "reduce" after
// the callback.
// #3 If the user is not playing, we add the user object to the resulting array
// #4 Finally, "reduce" returns the array that was passed as second argument
// and contains user objects not playing ;)
var usersNotPlaying = Object.keys(users).reduce(function (result, userName) {
if (!users[userName].isPlaying)
result.push(users[userName]);
return result;
}, []); // <-- [] is the new array which will accumulate each user not playing
Clearly using Array.prototype.reduce
concentrates both map
and filter
in a single loop and, in large array, reducing should outperform "filter+map" approach, because looping a large array twice once to filter users not playing and looping again to map them into objects again can be heavy...显然,使用Array.prototype.reduce
将map
和filter
集中在一个循环中,并且在大数组中,reduce 应该优于“filter+map”方法,因为循环一次大数组两次以过滤不播放的用户并再次循环以映射它们再次进入物体可能很重......
Summary: I would still use filter+map over reduce when we talk about few items because sometimes readability/productivity is more important than optimization, and in our case, it seems like filter+map approach requires less explanations (self-documented code!) than reduce.总结:当我们谈论很少的项目时,我仍然会使用filter+map 而不是reduce ,因为有时可读性/生产力比优化更重要,在我们的例子中,似乎filter+map方法需要更少的解释(自我记录的代码!)比减少。
Anyway, readability/productivity is subjective to who does the actual coding...无论如何,可读性/生产力取决于谁进行实际编码......
Iterate through your users object:遍历您的用户对象:
var list = [];
for (var key in users) {
if (users[key].isPlaying === false) {
list.push(key);
}
}
This will give you a list of all users who have an isPlaying
property that is false
.这将为您提供isPlaying
属性为false
的所有用户的列表。
If you would like all of the user objects where isPlaying
is false, you can add the objects themselves instead:如果您想要所有isPlaying
为 false 的用户对象,您可以添加对象本身:
var list = [];
for (var key in users) {
if (users[key].isPlaying === false) {
list.push(users[key]);
}
}
This can also be achieved using Array.prototype.reduce , which is a great all round tool.这也可以使用Array.prototype.reduce来实现,这是一个很棒的全能工具。 It starts with getting an array of the names:它从获取名称数组开始:
var userNames = Object.keys(users);
To return an array just the user names where isPlaying is false, you can do:要仅返回isPlaying为 false 的用户名数组,您可以执行以下操作:
var usersNotPlaying = userNames.reduce(function(names, name) {
if (!users[name].isPlaying) {
names.push(name);
}
return names}, []);
To return an object of user objects with their names as keys is similar:以用户名作为键返回用户对象的对象是类似的:
var usersNotPlaying = userNames.reduce(function(names, name) {
if (!users[name].isPlaying) {
names[name] = users[name];
}
return names}, {});
You could also use forEach in a similar way, however since it returns undefined the object or array collecting the members must be initialised in an outer scope first:您也可以以类似的方式使用forEach ,但是由于它返回undefined,因此收集成员的对象或数组必须首先在外部范围内初始化:
var usersNotPlaying = {};
userNames.forEach(function(name) {
if (!users[name].isPlaying) {
usersNotPlaying[name] = users[name];
}
});
You can also use for..in :您还可以使用for..in :
var usersNotPlaying = {};
for (var user in users) {
if (users.hasOwnProperty(user) && !users[user].isPlaying) {
usersNotPlaying[user] = users[user];
}
}
All of the above can return an array of names, array of user objects or object of user objects.以上所有都可以返回名称数组、用户对象数组或用户对象对象。 Choose whatever suits.选择任何适合的。 ;-) ;-)
Please try the JS code below: set all the isPlaying to false.请尝试下面的 JS 代码:将所有 isPlaying 设置为 false。
var json_object={};//{"user1":{"isPlaying":"false"},"user2":{"isPlaying":"ture"}};
json_object['user1']={"isPlaying":"false"};
json_object['user2']={"isPlaying":"ture"};
console.log(json_object);
for(var key in json_object){
if(json_object[key].isPlaying === "false"){/*do what you want*/}
}
console.log(json_object);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.