2016-09-30 3 views
0

Ich habe eine JSON-Antwort und ich möchte diese JSON-Daten mit Rekursion vereinfachen und zu reduzieren. Ich schreibe eine Funktion, an dieser Stelle stecke ich fest. Ich möchte alle Datenelemente entfernen und ein neues Objekt ohne Datennamen erstellen.Javascript Rekursion normalisieren JSON-Daten

Meine json Daten wie diese

[ 
    { 
     "city": { 
      "data": { 
       "id": 649442, 
       "country_id": 54, 
       "state_id": 682, 
       "city_name": "Prague", 
       "state_name": "Praha" 
      } 
     }, 
     "country": { 
      "data": { 
       "id": 54, 
       "data": { 
        "country_name": "Czech Republic", 
        "short_country": "CZ", 
        "olympic_code": "CZE" 
       } 
      } 
     } 
    } 
] 

Und meine Funktion ist hier:

function normalizeData(object) { 
    return Object.keys(object).reduce((finalObject, objectKey) => { 
    if (object[objectKey] && object[objectKey].data) { 
     finalObject[objectKey] = object[objectKey].data; 
     if (Array.isArray(finalObject[objectKey].data)) { 
     finalObject[objectKey] = object[objectKey].data.map(item => { 
      return normalizeData(item); 
     }); 
     } else { 
     finalObject[objectKey] = normalizeData(object[objectKey].data); 
     } 
    } else { 
     finalObject[objectKey] = object[objectKey]; 
    } 
    return finalObject; 
    }, {}); 
}; 

Am und ich bin immer noch Datenobjekt bekommen. Also, wo mache ich Fehler? Oder gibt es einen besseren Weg, dies zu tun?

+0

Willkommen bei SO Tan! Um Klarheit zu schaffen, möchten Sie bestimmte Schlüssel löschen und ein neues, gereinigtes Objekt erhalten. Recht? Aber was soll mit 'id = 54' geschehen? – Rajesh

+0

Ja, ich mag Typen Daten so id vermeiden: 54 ähnliche sein sollte { „Land“: { „id“: 54 } } –

+0

es würde helfen, wenn Sie ein Beispiel für die Eingabe setzen könnten und die erwartete Ausgabe. Vielen Dank. – acontell

Antwort

0

Dies ist eine Lösung ohne reduce(), die überprüft, ob die Objekteigenschaften nicht geerbt werden (hasOwnProperty()), und führt eine Rekursion für jede Eigenschaft durch, die ein Objekt selbst ist. Wenn der Eigenschaftenschlüssel data ist, werden alle Werte in das übergeordnete Objekt kopiert, und der Schlüssel data wird anschließend aus dem Objekt gelöscht. Dies ist, wo es schwierig wird, weil das data Objekt eine data Eigenschaft selbst haben kann, so dass dies überprüft werden muss und eine doppelte Rekursion angewendet werden muss.

var jsonStr = `{ 
 
    "city": { 
 
     "data": { 
 
      "id": 649442, 
 
      "country_id": 54, 
 
      "state_id": 682, 
 
      "city_name": "Prague", 
 
      "state_name": "Praha" 
 
     } 
 
    }, 
 
    "country": { 
 
     "data": { 
 
      "id": 54, 
 
      "data": { 
 
       "country_name": "Czech Republic", 
 
       "short_country": "CZ", 
 
       "olympic_code": "CZE" 
 
      } 
 
     } 
 
    } 
 
}`; 
 

 
var jo = JSON.parse(jsonStr); 
 

 
function normalize(obj) { 
 
    for (var key in obj) { 
 
     if (obj.hasOwnProperty(key)) { 
 
      if (typeof obj[key] === 'object') { 
 
       if (key === 'data') { 
 
        // check if data object also has a data property 
 
        if (obj[key].hasOwnProperty('data')) { 
 
         // double recursion 
 
         normalize(obj[key]); 
 
         normalize(obj); 
 
        } 
 
        else { 
 
         // copy all values to the parent 
 
         // (only if they don't exist in the parent yet) 
 
         for (var subKey in obj[key]) { 
 
          if (obj[key].hasOwnProperty(subKey) 
 
          && !obj.hasOwnProperty(subKey)) { 
 
           obj[subKey] = obj[key][subKey]; 
 
          } 
 
         } 
 
         // remove the data key 
 
         delete obj[key]; 
 
        } 
 
       } 
 
       else { 
 
        // recursion 
 
        normalize(obj[key]); 
 
       } 
 
      } 
 
     } 
 
    } 
 
} 
 

 
normalize(jo); 
 

 
console.log(jo);

können Sie eine deep extend verwenden, um eine Kopie des Objekts, dass man zunächst erstellen und zurück, wenn Sie die Funktion nicht wollen, um die Eingabe zu ändern.

+0

Danke, dass ich arbeite, gut. –

+1

OK, es ist eine Lösung, aber auch eine hochkomplizierte Funktion: Keine Trennung von Belangen, kaum wiederverwendbar. – ftor

+0

@ftor ja ist es, aber es ist auch nicht zu schwer, es wiederverwendbar zu machen, oder? –

0

Ich habe meinen Fehler gefunden. Ich habe ein Array über dem Objekt :) also habe ich den Code so korrigiert.

export function normalizeData(object) { 
    return Object.keys(object).reduce((finalObject, objectKey) => { 
    if (object[objectKey] && object[objectKey].data) { 
     finalObject[objectKey] = object[objectKey].data; 
     if (Array.isArray(finalObject[objectKey].data)) { 
     finalObject[objectKey] = object[objectKey].data.map(item => { 
      return normalizeData(item); 
     }); 
     } else { 
     finalObject[objectKey] = normalizeData(object[objectKey].data); 
     } 
    } else { 
     finalObject[objectKey] = object[objectKey]; 
    } 
    return finalObject; 
    }, {}); 
} 

export function normalizeArray(array) { 
    return array.map(object => { 
    return normalizeData(object); 
    }) 
}