我有一个包含所有用户的对象,如下所示:var users = {user1:{}, user2:{}}
,每个用户都有一个isPlaying属性。如何获取所有isPlaying为false的用户?
我有一个包含所有用户的对象,如下所示:var users = {user1:{}, user2:{}}
,每个用户都有一个isPlaying属性。如何获取所有isPlaying为false的用户?
您应该使用 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];
});
// Compact and nicer!
var usersNotPlaying = Object.keys(users)
.filter(userName => users[userName].isPlaying)
.map(userName => users[userName]);
Array.prototype.reduce
正如 @RobG 所指出的,您也可以使用 Array.prototype.reduce
。
虽然我不想重复他的新答案,但我认为如果它返回一个未参加比赛的用户对象数组,那么reduce
方法更实用。
基本上,如果您返回一个对象而不是一个数组,问题在于另一个调用者(即调用执行所谓的reduce
的函数的函数)可能需要再次调用reduce
来执行新的操作,而数组已经准备好流畅地调用其他 Array.prototype
函数,如 map
, filter
, forEach
...
代码将如下所示:
// #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
显然使用 Array.prototype.reduce
将 map
和 filter
集中在单个循环中,在大型数组中,减少应该优于“filter+map”方法,因为对大型数组进行两次循环,一次过滤不玩游戏的用户,再次循环将它们映射回对象可能会很重...
总结:当涉及到少量项目时,我仍然会使用 filter+map 而不是 reduce,因为有时可读性/生产力比优化更重要,在我们的情况下,filter+map 方法需要的解释(自记录代码!)比 reduce 更少。
无论如何,可读性/生产力是由实际编码人员主观决定的...
userNames.reduce(function(names, name){if (!users[name].isPlaying) names.push(name); return names},[])
。或者使用箭头函数:userNames.reduce((names,name)=>users[name].isPlaying?names:names.push(name)&&names,[])
。但也许这开始变得有点晦涩了... - RobGreduce
不起作用。我错了吗? - Matías Fidemraizer遍历您的用户对象:
var list = [];
for (var key in users) {
if (users[key].isPlaying === false) {
list.push(key);
}
}
这将为您提供所有具有 isPlaying
属性为 false
的用户列表。
如果您想要所有 isPlaying
为 false 的用户对象,可以添加对象本身:
var list = [];
for (var key in users) {
if (users[key].isPlaying === false) {
list.push(users[key]);
}
}
var userNames = Object.keys(users);
var usersNotPlaying = userNames.reduce(function(names, name) {
if (!users[name].isPlaying) {
names.push(name);
}
return names}, []);
要返回一个以用户名作为键的用户对象的对象是相似的:
var usersNotPlaying = userNames.reduce(function(names, name) {
if (!users[name].isPlaying) {
names[name] = users[name];
}
return names}, {});
var usersNotPlaying = {};
userNames.forEach(function(name) {
if (!users[name].isPlaying) {
usersNotPlaying[name] = users[name];
}
});
var usersNotPlaying = {};
for (var user in users) {
if (users.hasOwnProperty(user) && !users[user].isPlaying) {
usersNotPlaying[user] = users[user];
}
}
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);