2012-02-03 20 views
8

jsfiddle link: http://jsfiddle.net/vN6fn/1/Come unire due matrici di oggetti JSON - rimuovendo duplicati e preservando l'ordine in Javascript/jQuery?

Si supponga che ho questi 2 oggetti:

var obj1 = { data: [ 
         {id:1, comment:"comment1"}, 
         {id:2, comment:"comment2"}, 
         {id:3, comment:"comment3"} 
        ] } 

var obj2 = { data: [ 
         {id:2, comment:"comment2"}, 
         {id:3, comment:"comment3"}, 
         {id:4, comment:"comment4"} 
        ] } 

e ultimo oggetto dovrebbe essere simile a questo:

var final = { data: [ 
         {id:1, comment:"comment1"}, 
         {id:2, comment:"comment2"}, 
         {id:3, comment:"comment3"}, 
         {id:4, comment:"comment4"} 
        ] } 

Qui ci sono alcune cose da considerare:

  • obj1 e obj2 può o non può avere duplicati

$.extend() sostituisce oggetti, $.merge() non rimuovere i duplicati (so che posso fare per il ciclo, ma sto cercando un modo migliore per fare questo).

+1

Non conservare la media dell'ordine (3, 4, 5, 1, 2), poiché l'oggetto 1 è il primo? –

+0

scusa per confonderti, posso cambiare la numerazione degli oggetti. – Sherzod

+0

@shershames Hm, questo non ha chiarito la mia confusione. Che cosa vuoi dire con questo? –

risposta

14

È possibile utilizzare $.merge e quindi passare e rimuovere i duplicati e quindi ordinarlo.

$.merge(obj1.data, obj2.data); 

var existingIDs = []; 
obj1.data = $.grep(obj1.data, function(v) { 
    if ($.inArray(v.id, existingIDs) !== -1) { 
     return false; 
    } 
    else { 
     existingIDs.push(v.id); 
     return true; 
    } 
}); 

obj1.data.sort(function(a, b) { 
    var akey = a.id, bkey = b.id; 
    if(akey > bkey) return 1; 
    if(akey < bkey) return -1; 
    return 0; 
}); 
+0

Lotto di ringraziamenti @Rocket Hazmat ..... – Patel

1

http://jsfiddle.net/J9EpT/

function merge(one, two){ 
    if (!one.data) return {data:two.data}; 
    if (!two.data) return {data:one.data}; 
    var final = {data:one.data}; 
    // merge 
    for(var i = 0 ; i < two.data.length;i++){ 
     var item = two.data[i]; 
     insert(item, final); 
    } 
    return final; 
} 


function insert(item, obj){ 
    var data = obj.data; 
    var insertIndex = data.length; 
    for(var i = 0; i < data.length; i++){ 
     if(item.id == data[i].id){ 
      // ignore duplicates 
      insertIndex = -1; 
      break; 
     } else if(item.id < data[i].id){ 
      insertIndex = i; 
      break; 
     } 
    } 
    if(insertIndex == data.length){ 
     data.push(item); 
    } else if(insertIndex != -1) { 
     data.splice(insertIndex,0,item); 
    } 
} 

var final = merge(obj1, obj2); 
3

Ecco una soluzione diretta jQuery:

function mergeDeep(o1, o2) { 
    var tempNewObj = o1; 

    //if o1 is an object - {} 
    if (o1.length === undefined && typeof o1 !== "number") { 
     $.each(o2, function(key, value) { 
      if (o1[key] === undefined) { 
       tempNewObj[key] = value; 
      } else { 
       tempNewObj[key] = mergeDeep(o1[key], o2[key]); 
      } 
     }); 
    } 

    //else if o1 is an array - [] 
    else if (o1.length > 0 && typeof o1 !== "string") { 
     $.each(o2, function(index) { 
      if (JSON.stringify(o1).indexOf(JSON.stringify(o2[index])) === -1) { 
       tempNewObj.push(o2[index]); 
      } 
     }); 
    } 

    //handling other types like string or number 
    else { 
     //taking value from the second object o2 
     //could be modified to keep o1 value with tempNewObj = o1; 
     tempNewObj = o2; 
    } 
    return tempNewObj; 
}; 

Demo con oggetti complessi. Ho trasformato questo in un post sul blog che mostra la differenza tra .extend() di jQuery e il mio script here.

+0

Esattamente quello che stavo cercando. Mi ha salvato un lavoro grazie! – hman

Problemi correlati