我有一个对象数组,它们都应该有相同的键,但缺少一些键。我想用通用值填写缺少的键。
我正在寻找一种简单的方法(本地或通过库),我现在使用的代码现在可以工作,看起来我的未经训练的眼睛相当沉重,我相信我重新创造了一些繁琐的方式来做某事,而有一个简单的一个。
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)
你的版本很好,虽然我可能会通过使用键构建一个对象(或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;
}
Re *** I'd change this
:请注意,存在且具有值undefined
的属性与根本不存在的属性之间存在差异。您的代码将它们视为同一个东西。当然,如果你知道他们没有价值undefined
(例如,因为你从它获得它们的API)...
您可以使用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);
这是一个使用对象文字中的属性扩展的版本,尽管这将具有非常有限的浏览器支持:
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);