Introduction

Soit un tableau d'objet qui contient des enregistrements semblables (avec les mêmes valeurs/même ordres) mais qui peuvent se répéter. Puisqu'il s'agit d'objet unique, on ne peut pas utiliser Array.prototype.indexOf. En SQL, on pourrait faire un SELECT DISTINCT.

Voici deux méthodes pour enlever les doublons. La première utilise un filter, la deuxième une boucle for. Il faut absolument générer une clé unique pour chaque objet qui sera insérer dans un objet. Le hash de l'objet sera plus rapide qu'un indexOf.

Avec filter

function removeDuplicateObject(arr) {
    var keys = {};
    return arr.filter(function(item) {
        var key = JSON.stringify(item);
        if (key in keys) {
            return false;
        }
        keys[key] = 1;
        return true;
    });
}

Avec for

function removeDuplicateObject(arr) {
    var keys = {};
    var a = [];
    for(var i = 0; i < arr.length; i++) {
        var item = arr[i];
        var key = JSON.stringify(item);
        if (key in keys) {
            continue;
        }
        keys[key] = 1;
        a.push(item);
    }
    return a;
}

Utilisation

// exemple 1, with inline object
var a = [
  {firstname: "Jane", lastname: "Smith"},
  {firstname: "John", lastname: "Smith"},
  {firstname: "Jane", lastname: "Smith"},
  {firstname: "John", lastname: "Smith"},
];
console.log(removeDuplicateObject(a));

// exemple 2, with date object
var a = [
  new Date(2015,0,3), 
  new Date(2015,0,2), 
  new Date(2015,0,3), 
  new Date(2015,0,2)
];
console.log(removeDuplicateObject(a));

Amélioration

La clé est générer grâce à JSON.stringify() et ne fonctionne donne pas avec des objets récursifs. On pourrait ajouter une fonction de rappel en deuxième paramètre [genkey] pour générer cette clé, exemple:

function removeDuplicateObject(arr, genkey) {
    var keys = {};
    return arr.filter(function(item) {
        var key = genkey(item);
        if (key in keys) {
            return false;
        }
        keys[key] = 1;
        return true;
    });
}

// on présume ici qu'on a un champ uid qui est unique
removeDuplicateObject(a, function(item) { return item.uid; })