如何在 JavaScript 中的另一个对象中找到具有属性的对象

laz*_*i19 2 javascript properties object

我的所有用户都有一个对象,如下所示:var users = {user1:{}, user2:{}}, 每个用户都有一个 isPlaying 属性。我如何让所有拥有 isPlaying 的用户都是假的?

Mat*_*zer 5

您应该使用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];
});
Run Code Online (Sandbox Code Playgroud)

如果使用 ECMA-Script 6 完成,您可以使用箭头函数:

// Compact and nicer!
var usersNotPlaying = Object.keys(users)
                       .filter(userName => users[userName].isPlaying)
                       .map(userName => users[userName]);
Run Code Online (Sandbox Code Playgroud)

使用 Array.prototype.reduce

正如@RobG 指出的那样,您也可以使用Array.prototype.reduce.

虽然我不想重叠他的新答案和自己的答案,但我相信reduce如果它返回一组用户对象not play,则该方法更实用。

基本上,如果您返回一个对象而不是数组,问题是另一个调用者(即调用执行所谓的那个的函数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
Run Code Online (Sandbox Code Playgroud)

显然,在单个循环中使用Array.prototype.reduce集中map和集中,并且filter在大数组中,减少应该优于“过滤器+映射”方法,因为循环一次大数组两次以过滤未播放的用户并再次循环以再次将它们映射到对象可能很重。 ..

总结:当我们谈论很少的项目时,我仍然会使用filter+map 而不是reduce,因为有时可读性/生产力比优化更重要,在我们的例子中,似乎filter+map方法需要更少的解释(自我记录的代码!)比减少。

无论如何,可读性/生产力取决于谁进行实际编码......