如何在JavaScript中找到另一个对象中包含属性的对象
我的所有用户都有一个对象,比如:如何在JavaScript中找到另一个对象中包含属性的对象,javascript,object,properties,Javascript,Object,Properties,我的所有用户都有一个对象,比如:var users={user1:{},user2:{},每个用户都有一个isplay属性。如何获取显示为false的所有用户?您应该使用对象.键,数组.原型.过滤器和数组.原型.映射: // This will turn users object properties into a string array // of user names var userNames = Object.keys(users); // #1 You need to filter
var users={user1:{},user2:{}
,每个用户都有一个isplay属性。如何获取显示为false的所有用户?您应该使用对象.键
,数组.原型.过滤器
和数组.原型.映射
:
// 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脚本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
,以执行新操作,而数组已经准备好流畅地调用其他数组。原型
函数,如映射
,过滤器
,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
/#1我们将用户属性转换为属性名称数组
//#2然后在用户属性名数组中调用“reduce”。减少
//接受将为每个数组项调用并接收的回调
//作为“reduce”后的第二个参数给出的数组引用
//回调。
//#3如果用户没有播放,我们将用户对象添加到结果数组中
//#4最后,“reduce”返回作为第二个参数传递的数组
//并且包含未播放的用户对象;)
var usersNotPlaying=Object.keys(users).reduce(函数(结果,用户名){
如果(!users[userName].isplay)
结果推送(用户[用户名]);
返回结果;
}, []); // 遍历用户对象:
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]);
}
}
请尝试下面的JS代码:将所有显示设置为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);
这也可以通过使用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,但由于它返回未定义的对象或数组,因此必须首先在外部范围内初始化收集成员的对象或数组:
var usersNotPlaying = {};
userNames.forEach(function(name) {
if (!users[name].isPlaying) {
usersNotPlaying[name] = users[name];
}
});
您还可以在中使用..:
所有这些都可以返回名称数组、用户对象数组或用户对象对象对象数组。选择适合你的东西。;-) 您必须迭代每个玩家并检查该属性。如果您正在使用诸如jQuery或下划线之类的库,那么您应该能够利用它们的一些帮助函数来实现此…@Lix Vanilla JS>jQuery/下划线forthis@MatíasFidemraizer-您是在谈论性能/可读性/方便性吗?这完全取决于环境。。。虽然您的陈述在大多数情况下可能是正确的,但这并不是适用于JS用法的每个实例的一般规则…@Lix No.但是这个例子是有意义的。为什么在ECMA脚本5.x足够的情况下使用lib。请在浏览器的调试模式下查看console.log结果。我不理解您的解决方案@Matías Fidemraizer让在/*中显示为false的用户做你想做的*/或者将其构造成其他数据格式。还有为什么你使用字符串而不是实际的布尔0_oSorry,我的测试错误。。。布尔语肯定有用。谢谢~~您可以使用reduce:用户名。reduce(函数(名称,名称){if(!users[name].isplay)名称。push(名称);return names},[])
。或者使用箭头函数:userNames.reduce((name,name)=>users[name].isplay?name:names.push(name)&&name,[])
。但也许这开始变得有点模糊了…@robg-uhm你说得对。现在我不在家,但我会在打开笔记本电脑后尽快更新答案;)@RobG我认为你是对的,顺便说一句,我相信reduce
在这种情况下不起作用。我错了吗?reduce是少了一个方法调用。它是否合适(即“运行良好”)取决于操作,我想。@RobG如果您使用reduce方法提供答案,那就太好了。我不确定这种方法是否是解决这一具体问题的正确方法,因为它感觉“被迫”。。。注释中的示例代码将返回用户名数组而不是对象。。。为了完全理解如何获得与filter+map相同的结果,您是否可以添加一个答案或一个指向JSFIDLE或类似内容的链接;D
var usersNotPlaying = {};
for (var user in users) {
if (users.hasOwnProperty(user) && !users[user].isPlaying) {
usersNotPlaying[user] = users[user];
}
}