2012-12-13 9 views
5

consente di dare un'occhiata al seguente esempio:Javascript merge oggetto con proprietà nidificate

var ref = { 
    "fullName": { 
     "rules": { 
      "type": "string", 
      "minLength": 4, 
      "maxLength": 64 
     }, 
     "description": "Full name of a user." 
    } 
}; 

var user = { 
    "fullName": { 
     "rules": { 
      "required": true, 
      "maxLength": 128 
     }, 
     "message": "You have submitted a wrong full name." 
    } 
}; 

Ora quello che voglio è questa: Oggetti

  1. Unisci & proprietà.
  2. Tenere le proprietà del secondo oggetto se sono impostati già (maxLength)

Di seguito è riportato il risultato che mi aspetto:

var res = { 
    "fullName": { 
     "rules": { 
      "required": true, 
      "maxLength": 128 
      "type": "string", 
      "minLength": 4 
     }, 
     "description": "Full name of a user.", 
     "message": "You have submitted a wrong full name." 
    } 
}; 

Quello che ho cercato:

function mergeNestedObjects(firstObject, secondObject) { 
    var finalObject = {}; 

    for (var propertyKey in firstObject) { 
     var propertyValue = firstObject[propertyKey]; 

     if (typeof(propertyValue) === "object") { 
      finalObject[propertyKey] = mergeNestedObjects(firstObject[propertyKey], secondObject[propertyKey]); 
     } else if (secondObject[propertyKey] === undefined) { 
      finalObject[propertyKey] = firstObject[propertyKey]; 
     } else { 
      finalObject[propertyKey] = secondObject[propertyKey]; 
     } 
    } 

    return finalObject; 
} 

La funzione sopra si fonde ma in qualche modo non annida le proprietà.

UPDATE & RISPOSTA ottenuto che funziona, ho dimenticato troppo itterate attraverso il secondo oggetto, come muto. Grazie alla @AnthonyGrist

function mergeProperties(propertyKey, firstObject, secondObject) { 
    var propertyValue = firstObject[propertyKey]; 

    if (typeof(propertyValue) === "object") { 
     return mergeNestedObjects(firstObject[propertyKey], secondObject[propertyKey]); 
    } else if (secondObject[propertyKey] === undefined) { 
     return firstObject[propertyKey]; 
    } 

    return secondObject[propertyKey]; 
} 

function mergeNestedObjects(firstObject, secondObject) { 
    var finalObject = {}; 

    // Merge first object and its properties. 
    for (var propertyKey in firstObject) { 
     finalObject[propertyKey] = mergeProperties(propertyKey, firstObject, secondObject); 
    } 

    // Merge second object and its properties. 
    for (var propertyKey in secondObject) { 
     finalObject[propertyKey] = mergeProperties(propertyKey, secondObject, firstObject); 
    } 

    return finalObject; 
} 
+2

Stai sempre e solo iterare sulle chiavi del 'firstObject', così il vostro oggetto risultante è sempre e solo sta per avere gli stessi tasti come il primo oggetto passato in. Avrete anche bisogno di iterare i tasti di 'secondObject', e aggiungere quelli che mancano. –

+1

@onlineracoon: ho provato il codice e le proprietà sono nidificate correttamente. L'unico problema è che mancano alcune proprietà, come ha sottolineato Anthony. – RonaldBarzell

+0

@AnthonyGrist che ha funzionato, che stupido da parte mia. Ora però ho ottenuto questo: http://pastebin.com/Zma8kLY6 può essere reso più breve, sembra im fare molto del codice duplicato – onlineracoon

risposta

6
function mergeProperties(propertyKey, firstObject, secondObject) { 
    var propertyValue = firstObject[propertyKey]; 

    if (typeof(propertyValue) === "object") { 
     return mergeNestedObjects(firstObject[propertyKey], secondObject[propertyKey]); 
    } else if (secondObject[propertyKey] === undefined) { 
     return firstObject[propertyKey]; 
    } 

    return secondObject[propertyKey]; 
} 

function mergeNestedObjects(firstObject, secondObject) { 
    var finalObject = {}; 

    // Merge first object and its properties. 
    for (var propertyKey in firstObject) { 
     finalObject[propertyKey] = mergeProperties(propertyKey, firstObject, secondObject); 
    } 

    // Merge second object and its properties. 
    for (var propertyKey in secondObject) { 
     finalObject[propertyKey] = mergeProperties(propertyKey, secondObject, firstObject); 
    } 

    return finalObject; 
} 
+0

C'è un difetto in questo. Questo fallisce quando uniamo a = {a: {z: 1}, b: {y: 1}, c: {z: 1}}; b = {c: {zye: 1}}; Perché non stiamo controllando se la chiave esiste nel secondo oggetto della chiamata: return mergeNestedObjects (firstObject [propertyKey], secondObject [propertyKey]) – Abhinav

1

Abbastanza vecchia questione, ma può essere utile. Un po 'di ricorsione.

function mergeObjects(og, so) { 
    for (var key in so) { 
     if (typeof (og[key]) === 'object') { 
      mergeObjects(og[key], so[key]); 
     } else { 
      if (og[key] || typeof (og[key]) === 'boolean') { 
       og[key] = so[key]; 
      } 
     } 
    } 
    return og; 
} 

mergeObjects(ref, user); 
Problemi correlati