2014-11-15 20 views
6
Object1 = {connectorIndex: 1, nodeID: 6, Connectors: Object} 
Object2 = {connectorIndex: 1, nodeID: 6, Connectors: Object} 
Connector: {name: "ALAND", key: "", description: "Departure country (country from which the goods are sent)"} 

Ci sono due oggetti nello stesso array. Gli oggetti connettore sono identici. Come rimuovere elementi duplicati e ottenere l'array finale con un oggetto?Rimuovere gli oggetti duplicati in una matrice di oggetti in JavaScript

var array = [object 1, object 2]; 

object 2 è il duplicato per rimuovere dalla matrice.

+0

Non vi sono oggetti duplicati, due oggetti non sono mai uguali, quindi confrontare gli oggetti è complicato, se c'è un altro modo per risolverli, probabilmente è meglio, altrimenti dovresti controllare ogni proprietà con iterazioni ricorsive per confrontare anche l'oggetto di riferimento ecc. – adeneo

risposta

13

questo lo farebbe, se siete alla ricerca di corrispondenze esatte:

function remove_duplicates(objectsArray) { 
    var usedObjects = {}; 

    for (var i=objectsArray.length - 1;i>=0;i--) { 
     var so = JSON.stringify(objectsArray[i]); 

     if (usedObjects[so]) { 
      objectsArray.splice(i, 1); 

     } else { 
      usedObjects[so] = true;   
     } 
    } 

    return objectsArray; 

} 

var objectsArray = [{a:'foo',b:'bar'}, {a:'foo',b:'bar'}]; 
var clean = remove_duplicates(objectsArray); 
+0

ha funzionato ma se ho 3 oggetti simili non funziona #Jonathan Crowe –

+0

Quali sono gli oggetti? Questo codice rimuoverà solo le corrispondenze esatte degli oggetti. Forse stai cercando di rimuovere i dati corrispondenti anche se ci sono corrispondenze parziali? –

+0

Object1 = {connectorIndex: 1, nodeID: 6, Connectors: Object} Object2 = {connectorIndex: 1, nodeID: 6, Connectors: Object} Object3 = {connectorIndex: 1, nodeID: 6, Connectors: Object} Object4 = {connectorIndex: 1, nodeID: 6, Connectors: Object} –

3

La sfida con l'utilizzo di JSON.stringify è che se l'oggetto potrebbe contenere un riferimento circolare, allora sarà un'eccezione, per esempio

var x1 = {}; 
x1.a = x1; 
JSON.stringify(x1); // <- Uncaught TypeError: Converting circular structure to JSON 

Come accennato però, se si confrontano gli oggetti e non i valori, allora non si può semplicemente fare un confronto di uguaglianza, in quanto questo sarà sempre falso per gli oggetti differenti (anche se hanno le stesse proprietà con gli stessi valori).

Se si stavano semplicemente confrontando i valori, quindi qualcosa di simile al di sotto avrebbe funzionato

var x = [1,2,2,3,4,2,6]; // Source list 
var x2 = [];    // Will hold the de-duped result 
x.forEach(function(elem){if(x2.indexOf(elem) === -1) x2.push(elem);}); 
x2;      // <- [1, 2, 3, 4, 6] 

Se si desidera confrontare le proprietà degli oggetti di un livello si potrebbe scrivere qualcosa di simile al di sotto (ci può essere un modo più semplice - appena frustato questo insieme)

function sameValues(o1, o2){ 
    for(p in o1){ 
     if(o1[p] !== o2[p]) return false; 
    } 
    for(p in o2){ 
     if(o2[p] !== o1[p]) return false; 
    } 
    return true; 
} 

var Object1 = {connectorIndex: 1, nodeID: 6, Connectors: Object}; 
var Object2 = {connectorIndex: 1, nodeID: 6, Connectors: Object}; 
var Object3 = {connectorIndex: 1, nodeID: 7, Connectors: Object}; 
var Object4 = {connectorIndex: 2, nodeID: 7, Connectors: Object}; 
var Object5 = {connectorIndex: 1, nodeID: 7, Connectors: Object}; 
var arr = [Object1, Object2, Object3, Object4, Object5]; 

var result = []; 
arr.forEach(function(e1){ 
    if(!result.some(function(e2){return sameValues(e1,e2);})){ 
     // No existing object with same top level values in target array, so add 
     result.push(e1); 
    } 
}); 
// result will have the 1st, 3rd, and 4th object only 
+0

funziona solo quando obj1 obj2 è in ordine ... se obj1 obj4 obj3 se in questo non funziona –

+0

Funziona per me. Sicuro copi/incollato giusto? Se faccio il codice sopra ma con l'array come "var arr = [Object1, Object4, Object3, Object2, Object5];" poi vedo Object1, Object4 e Object3 nell'output, e gli altri rimossi - che è ciò che ti aspetteresti come Object2 e Object 5 sono duplicati. –

0

Utilizzare un array per contenere gli elementi che hai già e utilizzare il filtro()

var keys = [] 
yourArray.filter(function(v) { 
    if (keys.indexOf(v.whatIAmLookingFor) < 0) { 
    keys.push(v.whatIAmLookingFor) 
    return true 
    } 
    return false 
}) 

Avvolgilo in una funzione e chiamalo un giorno. Passa in una funzione per il test e chiamala un giorno ancora migliore.

1

Questo è come io preferisco rimuovere gli oggetti duplicati da JavaScript nell'edificio-

var fieldArray = [{ "name": "tom", "text": "tasty" },{ "name": "ram", "text": "rty" },{ "name": "ram", "text": "rty" },{ "name": "shyam", "text": "tasty" },{"name": "ram", "text": "rty" },{ "name": "tom", "text": "tasty" }]; 
 
fieldArray = fieldArray.reduce(function(field, e1){ 
 
\t var matches = field.filter(function(e2){return e1.name== e2.name}); 
 
\t if (matches.length == 0){ 
 
\t \t field.push(e1); 
 
\t }return field; 
 
}, []); 
 
alert(JSON.stringify(fieldArray));

Questo funziona perfetto per me.

0

Non so quanto performante questo è, ma ho un po 'come è per la sua concisione, funziona per me (il suo ES6, ma sono sicuro che si poteva capire la pianura ol' ES5):

let dedupe = (arr, keys) => { 
    let deduped = []; 
    arr.forEach(i => { 
    if (deduped.length === 0) { 
     deduped.push(i); 
    } else { 
     let exists = deduped.find(x => { 
     return keys.every(key => { 
      return i[key] === x[key]; 
     }); 
     }); 
     if (!exists) { 
     deduped.push(i); 
     } 
    } 
    }); 
    return deduped; 
}; 

objArr = dedupe(objArr, ['key', 'test', 'foo']); 
Problemi correlati