我的所有用户都有一个对象,如下所示:var users = {user1:{}, user2:{}}
,并且每个用户都有一个isPlaying属性。如何让所有使用isPlaying的用户出错?
答案 0 :(得分:4)
您应该使用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];
});
如果使用ECMA-Script 6完成,您可以使用箭头功能:
// 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
方法会更实用。< / p>
基本上,如果你返回一个对象而不是一个数组,问题是另一个调用者(即一个调用所谓的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
和[]
集中在一个循环中,并且在大数组中,缩小应该优于&#34; filter + map&#34;方法,因为将一个大型数组循环两次以过滤不再播放的用户并再次循环以将它们再次映射到对象中可能很重...
总结:当我们谈论几个项目时,我仍会使用 filter + map 而不是 reduce ,因为有时可读性/生产力比优化更重要,在我们的例子中,似乎 filter + map 方法需要较少的解释(自我记录的代码!)而不是reduce。
无论如何,可读性/生产力对于谁进行实际编码是主观的......
答案 1 :(得分:1)
遍历您的用户对象:
isPlaying
这将为您提供false
属性为isPlaying
的所有用户的列表。
如果您希望var list = [];
for (var key in users) {
if (users[key].isPlaying === false) {
list.push(users[key]);
}
}
为假的所有用户对象,则可以自行添加对象:
{{1}}
答案 2 :(得分:1)
这也可以使用 Array.prototype.reduce 来实现,这是一个很棒的全能工具。它首先得到一个名称数组:
var userNames = Object.keys(users);
要返回一个数组,只是 isPlaying 为false的用户名,你可以这样做:
var usersNotPlaying = userNames.reduce(function(names, name) {
if (!users[name].isPlaying) {
names.push(name);
}
return names}, []);
要返回 user 对象的对象,其名称与键类似:
var usersNotPlaying = userNames.reduce(function(names, name) {
if (!users[name].isPlaying) {
names[name] = users[name];
}
return names}, {});
您也可以以类似的方式使用 forEach ,但由于它返回 undefined ,因此必须首先在外部作用域中初始化收集成员的对象或数组:
var usersNotPlaying = {};
userNames.forEach(function(name) {
if (!users[name].isPlaying) {
usersNotPlaying[name] = users[name];
}
});
您也可以使用 for..in :
var usersNotPlaying = {};
for (var user in users) {
if (users.hasOwnProperty(user) && !users[user].isPlaying) {
usersNotPlaying[user] = users[user];
}
}
以上所有内容都可以返回一组名称,用户对象数组或用户对象对象。选择任何适合的。 ; - )
答案 3 :(得分:-1)
请尝试以下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);