2012-02-03 45 views
8

jsFiddle enlace: http://jsfiddle.net/vN6fn/1/¿Cómo combinar dos matrices de objetos JSON? ¿Eliminar duplicados y conservar el orden en JavaScript/jQuery?

Supongamos que tengo estos 2 objetos:

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"} 
        ] } 

y último objeto debe tener este aspecto:

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

Aquí están algunas cosas a considerar:

  • obj1 y obj2 puede o no tener duplicados

$.extend() reemplaza objetos, $.merge() no elimina los duplicados (sé que puedo hacer por bucle, pero estoy buscando una mejor manera de hacer esto).

+1

¿No preservaría el orden de la orden (3, 4, 5, 1, 2), ya que el objeto 1 es el primero? –

+0

siento confundirlo, puedo cambiar la numeración de los objetos. – Sherzod

+0

@shershames Hm, eso no borró mi confusión. ¿Qué quieres decir con eso? –

Respuesta

14

Puede usar $.merge y luego examinar y eliminar los duplicados, y luego ordenarlos.

$.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

Muchas gracias @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

Aquí es una solución recta 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 objetos complejos. He convertido esto en una publicación de blog que muestra la diferencia entre jQuery's .extend() y mi script here.

+0

Exactamente lo que estaba buscando. Me salvó un trabajo gracias! – hman

Cuestiones relacionadas