Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery unique objects based on specific object properties

I want an array of unique objects, removing duplicate objects which have some specific property values. For example: in the code snippet below, event1 and event2 have same title and same start value, event3 and event4 have same title but different start times.

I want to remove event2 from the object array (as it has same title and start value as event1) but not event4 (as it has only same title).

My code looks like:

var event1 = {id: 1, title: 'ABC', start: '10'};
var event2 = {id: 2, title: 'ABC', start: '10'};
var event3 = {id: 3, title: 'DEF', start: '12'};
var event4 = {id: 4, title: 'DEF', start: '20'};

var a=[];
a.push(event1);
a.push(event2);
a.push(event3);
a.push(event4);


//I tried this, but this code checks for title only.
var titles = [];
var b = [];

$.each(a, function(index, event) {
    if ($.inArray(event.title, titles) === -1) {
      titles.push(event.title);
      b.push(event);
    }
});

console.log(b); //Gives output as [Object { id=1, title="ABC", start="10"}, Object { id=3, title="DEF", start="12"}]
// The right output should be: [Object { id=1, title="ABC", start="10"}, Object { id=3, title="DEF", start="12"}, Object { id=3, title="DEF", start="20"}]

My code above only checks for title. I was unable to make it work for two different properties. Thanks for the help in advance.

like image 593
Lalu Avatar asked Nov 28 '14 18:11

Lalu


3 Answers

Try this:

var event1 = {id: 1, title: 'ABC', start: '10'};
var event2 = {id: 2, title: 'ABC', start: '10'};
var event3 = {id: 3, title: 'DEF', start: '12'};
var event4 = {id: 4, title: 'DEF', start: '20'};

var events = [event1, event2, event3, event4];

var result = events.reduce(function(memo, e1){
  var matches = memo.filter(function(e2){
    return e1.title == e2.title && e1.start == e2.start
  })
  if (matches.length == 0)
    memo.push(e1)
    return memo;
}, [])

console.log(result)
like image 140
Furqan Zafar Avatar answered Nov 14 '22 22:11

Furqan Zafar


For documentation, using jQuery:

$.each(a, function(index, event) {
    var events = $.grep(b, function (e) {
        return event.title === e.title &&
            event.start === e.start;
    });
    if (events.length === 0) {
      b.push(event);
    }
});

See demo

like image 27
dreyescat Avatar answered Nov 14 '22 22:11

dreyescat


As a function:

function distinctArrayBy(arr, propName) {
    var result = arr.reduce(function (arr1, e1) {
        var matches = arr1.filter(function (e2) {
            return e1[propName] == e2[propName];
        })
        if (matches.length == 0)
            arr1.push(e1)
        return arr1;
    }, []);

    return result;
}

Distinct by multiple properties:

function distinctArrayBy(arr, propNames) {
    var result = arr.reduce(function (arr1, e1) {
        var matches = arr1.filter(function (e2) {
            var matchResult = true;
            $.each(propNames, function (index, value) {
                matchResult = matchResult && e1[value] == e2[value];
            });
            return matchResult;
        });
        if (matches.length == 0)
            arr1.push(e1)
        return arr1;
    }, []);

    return result;
}
like image 45
Jacob Avatar answered Nov 14 '22 20:11

Jacob