demo
demo

Reputation: 6235

indexOf for array with different objects

I have an array of users.

When I click on button "Add New", I want to add new object to this array only if it doen't exist there:

var newUser = { 'creating': true, 'editMode': true };
if ($scope.users.indexOf(newUser) < 0) {
    $scope.users.push(newUser);
}

but indexOf always return -1.

Is this because array contain "different" objects?

enter image description here

Upvotes: 1

Views: 81

Answers (2)

Hitmands
Hitmands

Reputation: 14169

If you want to have a collection of unique values you should use ECMASCRIPT-6 Set

If you need to stay legacy, otherwise, you need to use arrays...

var Set = (function() {
  function Set() {}
  
  Set.prototype.has = function(val) {
    return !!this._list.filter(i => i.id === val.id).length;
  };
  
  Set.prototype.get = function(val) {
    if(!val) {
      return this._list;
    }
    
    return this._list.filter(i => i.id === val.id).pop();
  };
  
  Set.prototype.add = function(val) {
    if(!this.has(val)) {
      this._list.push(val)
    }
    
    return this;
  }
  
  return Set;
})();

Upvotes: 0

Py.
Py.

Reputation: 3599

I suppose each time you're going to call "Add New", it'll work (hard to say without more code). For the simple reason that each instance of newUser is a different one.

The indexOf calls check for exactly this instance of newUser. It doesn't check the property values, just for the reference to the instance.

e.g. :

var user = {a : "b"};
var users = [];
users.push(user);
users.indexOf(user); // returns 0, reference the user created at the top, inserted beforehand
user = {a : "b"};
users.indexOf(user); // returns -1, reference the user created just above, not yet inserted

If you want to check for instance, you'll have to make a check on a property (name, id, ...)

Upvotes: 1

Related Questions