Pregunta

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 indexOf function doesn't accept properties, only values. To use it, I'd have to first user findWhere and then pass what that returns into indexOf:

var valueOfUpdatedUser = _.findWhere(users, { userId: updatedUser.userId })
var indexOfUpdatedUser = _.indexOf(users, valueOfUpdatedUser)
users[indexOfUpdatedUser] = updatedUser;

A second approach would be to use reject to remove the matched user, and then push my updated user to the array.

Surely there's a better, simpler way?

¿Fue útil?

Solución

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(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).

Otros consejos

Unfortunately, underscore's indexOf function doesn't accept properties, only values.

In this case, what you can use instead of indexOf is to use findIndex

From the docs:

Similar to _.indexOf, returns the first index where the predicate truth test passes; otherwise returns -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)

Instead of an array, it would be easier an object with ids as property names:

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;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top