2

I'm trying to remove objectst from an array which have 4 identical values and 1 unique.

A quick google search gives a lot of options for removing identical objects from an array, but not objects that are similar.

Example of array:

var data = [
   {Date: "2016-04-27T09:03:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"},
   {Date: "2016-04-27T08:07:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"},
   {Date: "2016-04-27T10:23:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"}
]

I have tried using lodash _uniq function, but it only takes one property to match:

var non_duplidated_data = _.uniq(data, 'Name'); 

All values are identical except date. How can I remove identical objects based on 4 properties?

mplungjan
  • 169,008
  • 28
  • 173
  • 236
TietjeDK
  • 1,167
  • 2
  • 15
  • 43

4 Answers4

2

You can do this by two nested loops which will iterate the array against itself.

var newArray = [];   //Result array

//iterate
data.forEach(function(item, index){

    var found = false; 

    //Go through the rest of elements and see if any matches  
    for (var i = index; i < data.length, i++) {
        if (item.name == data[i].name && item.title == data[i].title) // add more fields here
            found = true;      
    }   

    //Add to the result array if no duplicates found
    if (!found)
       newArray.push(item);
})
Charlie
  • 22,886
  • 11
  • 59
  • 90
1

Use .uniqBy https://lodash.com/docs#uniqBy, it allows custom criteria to uniqify your array.

jcubic
  • 61,973
  • 54
  • 229
  • 402
DhruvPathak
  • 42,059
  • 16
  • 116
  • 175
  • I'm having a bit of trouble of understanding the syntax. I tried this `_.uniqBy($scope.data, "Job_Title", "Department");` which only computes based on the first parameter `Job_Title`. Any suggestions? – TietjeDK Apr 28 '16 at 09:11
  • @TietjeDK use good methods as given here : http://stackoverflow.com/questions/26306415/underscore-lodash-unique-by-multiple-properties – DhruvPathak Apr 28 '16 at 09:25
1

This could help you, in this code i start by mapping all properties that should be compared, then i reduce the array in order to get only the unique records.

 var data = [
       {Date: "2016-04-27T09:03:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"},
       {Date: "2016-04-27T08:07:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"},
       {Date: "2016-04-27T10:23:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"}
    ];

var uniqueRecord = data.map(function(item){
    return {Name:item.Name,Title:item.Title,Department: item.Department,Company:item.Company};
}).reduce(function(acc,curr){
    if(!Array.isArray(acc)){
        var copyOfAcc = JSON.parse(JSON.stringify(acc));
        acc = [];
        acc.push(copyOfAcc);
    }
    return (acc.indexOf(curr) > -1) ? acc.push(curr) : acc;

});

The result would be:

[ { Name: 'Tito',
    Title: 'Developer',
    Department: 'IT',
    Company: 'XXX' } ]

Then you would need to define which date you want to keep (first, last, which?) and find again the records, for this a simple 'forEach' should work.

Th0rndike
  • 3,406
  • 3
  • 22
  • 42
1

You can solve this using plain Javascript. Just check each object for each property:

Array.prototype.allValuesSame = function() {
    for(var i = 1; i < this.length; i++) {
        if(this[i] !== this[0])
            return false;
    }
    return true;
}

var data = [
   {Date: "2016-04-27T09:03:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"},
   {Date: "2016-04-27T08:07:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"},
   {Date: "2016-04-27T10:23:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"}
]

var tmpPropValues = {};
for (var property in data[0]) {
    tmpPropValues[property] = [];

    for(var i = 0; i < data.length; i++) {
        var obj = data[i];

    // store temporary in array
    if (obj.hasOwnProperty(property)) {
      var value = obj[property];

      tmpPropValues[property].push(value);
    }
  }

    if(tmpPropValues[property].allValuesSame()) {
      delete tmpPropValues[property];
  }
}

for(var prop in tmpPropValues) {
    var tmp = document.getElementById("result").innerHTML;
  document.getElementById("result").innerHTML = tmp+" "+prop;

}

I made a fiddle for you.

Manticore
  • 1,284
  • 16
  • 38