本文介绍了如何在 JavaScript 中的另一个对象中找到具有属性的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含所有用户的对象,如下所示:var users = {user1:{}, user2:{}},并且每个用户都有一个 isPlaying 属性.如何让所有使用 isPlaying 为 false 的用户?

I have a object with all my users, like so:var users = {user1:{}, user2:{}}, And every user has a isPlaying property. How do I get all users that have isPlaying false?

推荐答案

你应该使用 Object.keysArray.prototype.filterArray.prototype.map:

You should use Object.keys, Array.prototype.filter and 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 完成,您可以使用箭头函数:

If it would be done using ECMA-Script 6, you could do using arrow functions:

// 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 方法更实用,如果它返回一组用户对象未播放.

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的函数)可能需要调用再次reduce 执行新的操作,而一个数组已经准备好流畅地调用其他Array.prototype 函数,如mapfilter>, forEach...

Basically, if you return an object instead of an array, the issue is that another caller (i.e. 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...

代码看起来像这样:

// #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.reducemapfilter 集中在一个循环中,并且在大数组中,reduce 应该优于"filter+map" 的方法,因为循环一个大数组两次以过滤不播放的用户并再次循环以再次将它们映射到对象可能很重...

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...

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

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.

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

Anyway, readability/productivity is subjective to who does the actual coding...

这篇关于如何在 JavaScript 中的另一个对象中找到具有属性的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 22:01