javascript 如何在javascript中替换数组中的特定对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23642032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I replace a specific object in an array in javascript?
提问by adamdport
I have an array of users, and I'd like to update one of those users.
我有一组用户,我想更新其中一个用户。
users = [
{userId: 23, userName:"foo"},
{userId: 34, userName:"wrong"},
{userId: 45, userName:"baz"}
{userId: 56, userName:"..."},
]
updatedUser = {
userId: 34,
userName: bar
}
I'm using underscorejs. I thought the simplest way is to find the index of the user to be updated, and then just set the value of that user to my updated value. Unfortunately, underscore's indexOffunction doesn't accept properties, only values. To use it, I'd have to first user findWhereand then pass what that returns into indexOf:
我正在使用下划线。我认为最简单的方法是找到要更新的用户的索引,然后将该用户的值设置为我更新的值。不幸的是,underscore 的indexOf函数不接受属性,只接受值。要使用它,我必须首先使用findWhere,然后将返回的内容传递给 indexOf:
var valueOfUpdatedUser = _.findWhere(users, { userId: updatedUser.userId })
var indexOfUpdatedUser = _.indexOf(users, valueOfUpdatedUser)
users[indexOfUpdatedUser] = updatedUser;
A second approach would be to use rejectto remove the matched user, and then push my updated user to the array.
第二种方法是使用拒绝删除匹配的用户,然后将我更新的用户推送到数组。
Surely there's a better, simpler way?
肯定有更好、更简单的方法吗?
回答by Jon
You can use extend
after findWhere
. It's not technically the same as replacing the object with another instance entirely, but it eliminates the extra loop over the array:
extend
之后可以使用findWhere
。它在技术上与完全用另一个实例替换对象不同,但它消除了数组上的额外循环:
_.extend(_.findWhere(users, { userId: updatedUser.userId }), updatedUser);
If this is still not satisfactory then your best bet is probably to iterate manually.
如果这仍然不令人满意,那么您最好的选择可能是手动迭代。
I am deliberately leaving the "object properties keyed by user id" approach out of the discussion because in practice it's not uncommon to have an array in hand to begin with (e.g. the user array was retrieved by an API).
我有意将“由用户 ID 键控的对象属性”方法排除在讨论之外,因为在实践中,手头有一个数组并不少见(例如,用户数组是由 API 检索的)。
回答by Martin
Unfortunately, underscore's indexOf function doesn't accept properties, only values.
不幸的是,underscore 的 indexOf 函数不接受属性,只接受值。
In this case, what you can use instead of indexOf is to use findIndex
在这种情况下,您可以使用findIndex代替 indexOf
From the docs:
从文档:
Similar to _.indexOf, returns the first index where the predicate truth test passes; otherwise returns -1.
类似于_.indexOf,返回谓词真值测试通过的第一个索引;否则返回-1。
_.findIndex([4, 6, 8, 12], isPrime);
=> -1 // not found
_.findIndex([4, 6, 7, 12], isPrime);
=> 2
So in this case you'd do something like this:
所以在这种情况下,你会做这样的事情:
var indexOfUpdatedUser = _.findIndex(users, { userId: updatedUser.userId });
users[indexOfUpdatedUser] = updatedUser;
Update: A check for a -1 value would probably be a good idea (i.e. if the index isn't found)
更新:检查 -1 值可能是个好主意(即如果未找到索引)
回答by Oriol
Instead of an array, it would be easier an object with ids as property names:
使用 id 作为属性名称的对象而不是数组会更容易:
var users = {
23: {userName: "foo"},
34: {userName: "wrong"},
45: {userName: "baz"},
56: {userName: "..."}
};
Then, to update the data of some user, just use
然后,要更新某个用户的数据,只需使用
users[updatedUserId] = updatedUserData;