2017-12-18 5 views
2

オブジェクトの配列がすべて同じキーを持つ必要がありますが、一部のキーがありません。欠落しているキーに一般的な値を入力したいと思います。オブジェクトの配列に欠けているキーを埋める方法は?

私はこれを(ネイティブに、またはライブラリを介して)行うための簡単な方法を探しています。私が今使っているコードは、私の訓練されていない目をかなり重く見ていて、何かをする退屈な方法単純なものがありますが。

var arr = [{ 
 
    "a": 1, 
 
    "b": 2, 
 
    "c": 3 
 
    }, 
 
    { 
 
    "a": 10, 
 
    "c": 30 
 
    }, 
 
    { 
 
    "b": 200, 
 
    "c": 300 
 
    }, 
 
] 
 
// get the list of all keys 
 
var allkeys = [] 
 
arr.forEach((objInArr) => { 
 
    allkeys = allkeys.concat(Object.keys(objInArr)) 
 
}) 
 
// check all arr entries for missing keys 
 
arr.forEach((objInArr, i) => { 
 
    allkeys.forEach((key) => { 
 
    if (objInArr[key] === undefined) { 
 
     // the generic value, in this case 0 
 
     arr[i][key] = 0 
 
    } 
 
    }) 
 
}) 
 
console.log(arr)

+0

注:非常に限られたブラウザのサポートを持っていますそれはまったく存在しません。あなたのコードはそれらを同じものとして扱います。 –

+0

あなたは本当に事前に鍵を知らないのですか? –

+1

この場合のあなたのアプローチはOKのようですが、 'allkeys'には配列の代わりにセットを使うことを検討するかもしれません。コード内allkeys' 'の値は' [ "A"、 "B"、 "C"、 "A"、 "C"、 "B"、 "C" ]なってしまいます'、実際には' ["a"、 "b"、 "c"] 'でなければなりません。 – GolfWolf

答えて

1

あなたはデフォルトのキー値を保持するオブジェクトにそれぞれの要素をマージするObject.assignを使用することができます。

var arr = [{ 
 
    "a": 1, 
 
    "b": 2, 
 
    "c": 3 
 
    }, 
 
    { 
 
    "a": 10, 
 
    "c": 30 
 
    }, 
 
    { 
 
    "b": 200, 
 
    "c": 300 
 
    }, 
 
]; 
 
var defaultObj = arr.reduce((m, o) => (Object.keys(o).forEach(key => m[key] = 0), m), {}); 
 
arr = arr.map(e => Object.assign({}, defaultObj, e)); 
 
console.log(arr);

+1

これは、事前に鍵を知る必要があります。すべてのオブジェクトに存在するキーから 'defaultObj'を構築する追加のステップを実行するかもしれません。 – GolfWolf

+0

OPは事前にキーを知らない。 –

1

あなたのバージョンされ罰金、私はおそらくすべてのthを避けるだろうose配列concatは、キーを使ってオブジェクト(またはSet)を構築するだけで呼び出すことができます。それはfor-ofでも少し少ない不格好です:

var arr = [{ 
 
    "a": 1, 
 
    "b": 2, 
 
    "c": 3 
 
    }, 
 
    { 
 
    "a": 10, 
 
    "c": 30 
 
    }, 
 
    { 
 
    "b": 200, 
 
    "c": 300 
 
    }, 
 
]; 
 
// Get all the keys 
 
const keyObj = Object.create(null); 
 
for (const entry of arr) { 
 
    for (const key of Object.keys(entry)) { 
 
    keyObj[key] = true; 
 
    } 
 
} 
 
const allkeys = Object.keys(keyObj); 
 
// Check all arr entries for missing keys 
 
for (const entry of arr) { 
 
    for (const key of allkeys) { 
 
    if (entry[key] === undefined) { // ***I'd change this 
 
     entry[key] = 0; 
 
    } 
 
    } 
 
} 
 
console.log(arr);
.as-console-wrapper { 
 
    max-height: 100% !important; 
 
}

*** I'd change this:存在し、値undefinedを持つプロパティとは全く存在しないプロパティの違いがあることに注意してください。あなたのコードはそれらを同じものとして扱います。もちろん、値がundefinedではないことが分かっている場合は(例えば、APIを使用しているため)...

1

オブジェクトリテラルでプロパティスプレッドを使用しているバージョンです存在し、値 `undefined`や財産を持っている性質の違いがあること

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator

var arr = [{ 
 
    "a": 1, 
 
    "b": 2, 
 
    "c": 3 
 
    }, 
 
    { 
 
    "a": 10, 
 
    "c": 30 
 
    }, 
 
    { 
 
    "b": 200, 
 
    "c": 300 
 
    }, 
 
] 
 

 
// Create an object with all the keys in it 
 
// This will return one object containing all keys the items 
 
let obj = arr.reduce((res, item) => ({...res, ...item})); 
 

 
// Get those keys as an array 
 
let keys = Object.keys(obj); 
 

 
// Create an object with all keys set to the default value (0) 
 
let def = keys.reduce((result, key) => { 
 
    result[key] = 0 
 
    return result; 
 
}, {}); 
 

 
// Use object destrucuring to replace all default values with the ones we have 
 
let result = arr.map((item) => ({...def, ...item})); 
 

 
// Log result 
 
console.log(result);

+0

@ T.J.Crowderありがとう、私は気づいていませんでした。私は私の答えを更新しました。 – user184994

+0

:-)それはオブジェクトの破壊でもありません(ES2015では*でした)。それは「プロパティ拡散構文」です。 –

関連する問題