2016-09-30 13 views
0

私はjsonレスポンスを持っています。このjsonデータを再帰と簡約で簡素化したいと思います。私はこの時点で固まった関数を書く。私はすべてのデータ要素を削除し、データ名なしで新しいオブジェクトを作成したい。Javascript再帰JSONデータを正規化

私のJSONデータはこの

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

のようなもので、私の関数はここにある:で

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; 
    }, {}); 
}; 

と私はまだデータオブジェクトを取得しています。だからどこで私は間違っているのか。それとももっと良い方法がありますか?

+0

ようこそSO Tan!明確にするために、特定のキーを削除し、新しい、きれいにされたオブジェクトを取得します。右?しかし、 'id = 54'でどう対処すればよいでしょうか? – Rajesh

+0

はい、私はIDので、タイプのデータを避けたい:54は、この ようにする必要があります{{ 「ID」: 「国」54 } } –

+0

あなたが入力の例を置くことができれば、それが役立つだろうと期待される出力。ありがとう。 – acontell

答えて

0

reduce()のないソリューションで、オブジェクトのプロパティが継承されていないかどうかを確認し(hasOwnProperty())、オブジェクト自体の各プロパティに対して再帰を行います。プロパティーキーがdataの場合、すべての値が親オブジェクトにコピーされ、その後dataキーがオブジェクトから削除されます。これは、dataオブジェクトがdataプロパティを持つことができるので難しくなります。そのため、これをチェックして、二重再帰を適用する必要があります。

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);

あなたは関数が入力を変更したくない場合は、最初のオブジェクトのコピーを作成し、その1を返すようにdeep extendを使用することができます。

+0

私はうまく働いてくれてありがとう。 –

+1

OK、それは解決策ですが、非常に畳み込まれた機能です。懸念の分離はほとんどなく、再利用はほとんどありません。 – ftor

+0

@ftorはいそれはありますが、それを再利用可能にすることも難しくありませんか? –

0

私の間違いが見つかりました。オブジェクトの上に配列があります:)このようにコードを修正しました。

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); 
    }) 
}