如何填写对象数组中的缺失键?

问题描述 投票:2回答:3

我有一个对象数组,它们都应该有相同的键,但缺少一些键。我想用通用值填写缺少的键。

我正在寻找一种简单的方法(本地或通过库),我现在使用的代码现在可以工作,看起来我的未经训练的眼睛相当沉重,我相信我重新创造了一些繁琐的方式来做某事,而有一个简单的一个。

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)
javascript
3个回答
1
投票

你的版本很好,虽然我可能会通过使用键构建一个对象(或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)...


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
投票

这是一个使用对象文字中的属性扩展的版本,尽管这将具有非常有限的浏览器支持:

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);
© www.soinside.com 2019 - 2024. All rights reserved.