2014-01-29 131 views
7

我有1个数组,其中一个列表中包含具有唯一ID的所有用户列表。我有一个包含选定组信息的对象。部分信息是业主ID。我试图弄清楚,如何根据组所有者ID获取用户的信息?例如,学生组对象的所有者ID为70,我的网站上有一位ID为70的用户...我如何匹配它们?循环遍历对象数组以查找具有匹配属性的对象

users: 
[ { 
id: 68 
name: mike 
domain: i:0#.f|admembers|mike.ca 
email: mike.ca 
isAdmin: False 
}, etc etc ] 

selectedGroup: { 
name: Students 
id: 78 
description: 
owner: 70 
ownerIsUser: True 
} 

回答

18

你会通过users必须循环:

var i = users.length, 
    ownerData; 

while(i--) { 
    if(selectedGroup.owner == users[i].id) { 
     ownerData = users[i]; 
     break; 
    } 
} 

或者你可以使用Array.filter()

var ownerData = users.filter(function(user) { 
    return user.id === selectedGroup.owner; 
})[0]; 
+0

var i = users.length,ownerData;我从来没有见过这样的事情。什么是“我”? – Batman

+1

这是一种快速循环数组的方式 - 'i'初始化为'users'数组的长度,并在下面的while循环中递减。当'i'达到0时,循环执行最后的时间并结束。它以相反的顺序遍历数组。 –

+2

我了解索引部分,而不是ownerData部分。不应该像var i = x.length一样单独声明; var ownerData; – Batman

3

看一看Underscore.js轻视这一点,就像这样:

_.findWhere(users, { id: 68 }) 

Naturally你可以传递的一个变量匹配诸如:

_.findWhere(users, { id: selectedGroup.owner }) 
+0

包含一个实用程序功能库的错误形式。也许看看Underscore的'findWhere'实现并复制出来。 –

+0

我会建议把Underscore图书馆作为评论的一个更广泛的视角,因为它可能还有更多的收获,但我还没有能够对问题发表评论。 – swornabsent

1

你可以只在阵列上环,以匹配:

var match = function (array, matchfn) { 
    var i; 
    for (i in array) { 
     if (matchfn(array[i])) { 
      return array[i]; 
     } 
    } 
}; 

var user = match(users, function (u) { return u.id == 70; }); 
6

在ECMAScript中6,你可以使用本地Array.find method

var selectedUser = users.find(function(user){ 
    return user.id === 70; 
}); 

鉴于目前只有最新的Firefox支持此功能,您可以使用库如underscore.js

var selectedUser = _.find(users, function(user){ 
    return user.id === 70; 
}); 

...或者你可以使用一个包装围绕较远近期forEach method略:

var selectedUser; 

users.forEach(function(user){ 
    if(user.id === 70){ 
    selectedUser = user; 
    } 
}); 

但是,如果你想使用脚本将支持旧版浏览器,而无需使用库,你需要一个for循环:

var selectedUser; 

for(var i = 0; i < users.length; i++){ 
    if(users[ i ].id === 70){ 
    selectedUser = users[ i ]; 

    break; 
    } 
}; 
1

如果您有与现有的JavaScript对象的工作,我觉得蛮力解决方案是唯一的选择:

var owner; 
for(var i = 0; i < users.length; i++) { 
    if (users[i].id == selectedGroup.id) { 
     owner = users[i]; 
     break; 
    }   
} 

if (owner) { 
    console.log(owner); 
} 

取决于你如何使用它,它可能是更有效的调整你的第一个对象,所以你可以直接访问属性:

var users = { 
    "68": { 
     id: 68, 
     name: 'mike', 
     domain: 'i: 0#.f | admembers | mike.ca', 
     email: 'mike.ca', 
     isAdmin: false 
    } 
}; 

var selectedGroup = { 
    name: 'Students', 
    id: 78, 
    description: '', 
    owner: 68, 
    ownerIsUser: 'True' 
}; 

var owner = users[selectedGroup.owner]; 
+0

神圣的废话......我真的很喜欢将数组重构为对象的想法。这可能需要我重写我的服务,但稍后可能会使事情变得更简单。 – Batman

+0

我想重组对象已选中,但我不知道如何从循环创建一个新的属性。这是我尝试过的:http://jsfiddle.net/pGsc6/ – Batman

+0

请试试这个:http://jsfiddle.net/CJRUm/ –

0

您还可以使用Array.prototype.some比较所有的对象属性来查看它们是否包含相等的值。

function haveSameValues(oneObject, anotherObject) { 
    var hasDifferentKeyValues = Object.keys(oneObject).some(function(key){ 
    return oneObject[key] !== anotherObject[key] 
    }); 

    return !hasDifferentKeyValues; 
}