Christian68
Christian68

Reputation: 995

Underscore difference not working on array of JSON objects

I have a list of users that I want to filter, using _.difference. But it is not working on comparing the objects. It only works if I compare only the usernames. Here is the code snippet:

    var users = [
      {
        "username": "user1",
        "birthdate": "birth1"
      },
      {
        "username": "user2",
        "birthdate": "birth2"
      },
      {
        "username": "user3",
        "birthdate": "birth3"
      },
      {
        "username": "user4",
        "birthdate": "birth4"
      }
    ];

    var keep = [
      {
        "username": "user1",
        "birthdate": "birth1"
      },
      {
        "username": "user3",
        "birthdate": "birth3"
      }
    ];

    log(_.difference(_.pluck(users,"username"),_.pluck(keep,"username"))); // works
    log(_.difference(users,keep)); // this is what I want, does not work

Any idea? Thanks - C.

Note: an alternative way of doing it is as followss, but not sure about the efficiency:

        log( _.filter(users, function(num){
        return (!_.contains(_.pluck(keep,"username"),num.username))
    }) );

Upvotes: 1

Views: 808

Answers (1)

Emile Bergeron
Emile Bergeron

Reputation: 17430

These are arrays of objects, which are only seen as references (like addresses). Since they aren't references of the same object instances (even if they contain the same information), they are considered all different.

_.difference doesn't do a deep inspection of the arrays content, it just looks at the values and sees that they're object references.

If you want the objects

var users = [{ "username": "user1", "birthdate": "birth1" }, { "username": "user2", "birthdate": "birth2" }, { "username": "user3", "birthdate": "birth3" }, { "username": "user4", "birthdate": "birth4" }];
var keep = [{ "username": "user1", "birthdate": "birth1" }, { "username": "user3", "birthdate": "birth3" }];

// if you want to compare all the properties
var result = _.reject(users, _.partial(_.findWhere, keep, _));

console.log("All attributes", result);

// if the username is the identifying field
var keepUsernames = _.pluck(keep, 'username');
result = _.reject(users, (user) => _.indexOf(keepUsernames, user.username) > -1);

console.log("usernames", result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

Upvotes: 2

Related Questions