我有一组用户,我想更新其中一个用户。
users = [
{userId: 23, userName:"foo"},
{userId: 34, userName:"wrong"},
{userId: 45, userName:"baz"}
{userId: 56, userName:"..."},
]
updatedUser = {
userId: 34,
userName: bar
}
我正在使用underscorejs。我认为最简单的方法是找到要更新的用户的索引,然后将该用户的值设置为我更新的值。不幸的是,下划线的indexOf函数不接受属性,只接受值。要使用它,我必须先用户findWhere,然后将返回的内容传递给indexOf:
var valueOfUpdatedUser = _.findWhere(users, { userId: updatedUser.userId })
var indexOfUpdatedUser = _.indexOf(users, valueOfUpdatedUser)
users[indexOfUpdatedUser] = updatedUser;
第二种方法是使用reject删除匹配的用户,然后将我更新的用户推送到阵列。
当然有更好,更简单的方法吗?
答案 0 :(得分:23)
您可以在findWhere
之后使用extend
。它在技术上与完全用另一个实例替换对象不同,但它消除了数组上的额外循环:
_.extend(_.findWhere(users, { userId: updatedUser.userId }), updatedUser);
如果这仍然不能令人满意,那么你最好的选择可能是手动迭代。
我故意将“用户ID锁定的对象属性”方法排除在讨论之外,因为在实践中,手头有一个数组并不常见(例如用户数组是由API检索的)。
答案 1 :(得分:2)
不幸的是,下划线的indexOf函数不接受属性,只接受值。
在这种情况下,您可以使用而不是indexOf来使用findIndex
来自文档:
与_.indexOf类似,返回谓词真值测试通过的第一个索引;否则返回-1。
_.findIndex([4, 6, 8, 12], isPrime);
=> -1 // not found
_.findIndex([4, 6, 7, 12], isPrime);
=> 2
所以在这种情况下,你可以这样做:
var indexOfUpdatedUser = _.findIndex(users, { userId: updatedUser.userId });
users[indexOfUpdatedUser] = updatedUser;
更新:检查-1值可能是一个好主意(即如果找不到索引)
答案 2 :(得分:1)
使用id作为属性名称的对象将更容易,而不是数组:
var users = {
23: {userName: "foo"},
34: {userName: "wrong"},
45: {userName: "baz"},
56: {userName: "..."}
};
然后,要更新某些用户的数据,只需使用
users[updatedUserId] = updatedUserData;