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

How do I find objects with a property inside another object in JavaScript

本文关键字:一个对象 内部 属性 对象 JavaScript      更新时间:2023-09-26

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

您应该使用Object.keys, Array.prototype.filterArray.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的函数)可能需要再次调用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.reducemapfilter集中在单个循环中,并且在大型数组中,减少应该优于"filter+map"方法,因为循环大数组两次以过滤不玩的用户,然后再次循环将它们映射到对象中可能会很重…

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

无论如何,可读性/生产力是主观的,谁来做实际的编码…

遍历用户对象:

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]);
    }
}

这也可以使用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}, []);

返回一个用户对象的对象,它们的名字作为键,类似:

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];
  }
});

在:

中也可以用代替…
var usersNotPlaying = {};
for (var user in users) {
  if (users.hasOwnProperty(user) && !users[user].isPlaying) {
    usersNotPlaying[user] = users[user];
  }
}

以上所有方法都可以返回一个名称数组、用户对象数组或用户对象的对象。选择合适的。: -)

请尝试下面的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);