Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript - find unique objects in array based on multiple properties

Tags:

I need to find unique objects from array based on 2 properties as below. When "class" and "fare" match, I need to pull out unique values and get them in results array.

Source:

var arr = [{class:"second", fare: "a"}, 
 {class:"second", fare: "b"},
 {class:"first", fare: "a"},
 {class:"first", fare: "a"},
 {class:"second", fare: "a"},
 {class:"first", fare: "c"}
]

Expected result:

var result = [{class:"second", fare: "a"},
 {class:"second", fare: "b"},
 {class:"first", fare: "a"},
 {class:"first", fare: "c"}
]

I looked over in SO and was able to find answer which is filtered based on one property (Create array of unique objects by property), but couldn't find which could do based on 2 properties.

like image 450
whyAto8 Avatar asked Jul 27 '16 12:07

whyAto8


People also ask

How do you unique an array?

You can find the distinct values in an array using the Distinct function. The Distinct function takes the array as an input parameter and returns another array that consists only of the unique, or non-duplicate, elements.


1 Answers

You could build a combined key for the hash table and filter the given array.

var arr = [{ class: "second", fare: "a" }, { class: "second", fare: "b" }, { class: "first", fare: "a" }, { class: "first", fare: "a" }, { class: "second", fare: "a" }, { class: "first", fare: "c" }],
    result = arr.filter(function (a) {
        var key = a.class + '|' + a.fare;
        if (!this[key]) {
            this[key] = true;
            return true;
        }
    }, Object.create(null));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

The same without (mis)using thisArg of Array#filter.

var array = [{ class: "second", fare: "a" }, { class: "second", fare: "b" }, { class: "first", fare: "a" }, { class: "first", fare: "a" }, { class: "second", fare: "a" }, { class: "first", fare: "c" }],
    seen = Object.create(null),
    result = array.filter(o => {
        var key = ['class', 'fare'].map(k => o[k]).join('|');
        if (!seen[key]) {
            seen[key] = true;
            return true;
        }
    });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 142
Nina Scholz Avatar answered Sep 22 '22 09:09

Nina Scholz