我有一个对象数组,希望数组中的每个对象都有相同的键.

var obj1 = {"type": "test", "info": "a lot", "value": 7};
var obj2 = {"value": 5};
var obj3 = {"context": "demo", "info": "very long", "value": 3};
var obj4 = {"info": "no way"};

var dataSet = [obj1,obj2,obj3,obj4];

我的try 是在第一步创建一个包含所有可能键的array.

keys.forEach(function(a,b){
  dataSet.forEach(function(c,d){    
    //key not found
    if(a in c === false)
    {
      //add key to object 
      dataSet[b][a] = false;
    }
  });
});

然而,它似乎不能正常工作.

after logic:  [
  {
    "type": false,
    "info": "a lot",
    "value": 7
  },
  {
    "value": 5,
    "info": false
  },
  {
    "context": "demo",
    "info": "very long",
    "value": false
  },
  {
    "info": "no way",
    "context": false
  }
]

我错过了什么?

var obj1 = {"type": "test", "info": "a lot", "value": 7};
var obj2 = {"value": 5};
var obj3 = {"context": "demo", "info": "very long", "value": 3};
var obj4 = {"info": "no way"};

var dataSet = [obj1,obj2,obj3,obj4];
var keys    = [];

console.log("before logic: ", dataSet);

//Step 1: Fill keys array
dataSet.forEach(function(a,b){  
  Object.keys(a).forEach(function(c,d)
  {
    //add keys to array if not already exists
    if(!keys.includes(c))
    {
      keys.push(c);
    }
  });
});

//Step2: loop through keys array and add key to object if not existing
keys.forEach(function(a,b){
  dataSet.forEach(function(c,d){    
    //key not found
    if(a in c === false)
    {
      //add key to object 
      dataSet[b][a] = false;
    }
  });
});

console.log("after logic: ", dataSet);

EDIT:

如果 keys 也总是按同样的顺序排序,那就太完美了.

推荐答案

您只需使用flatMap()收集Set中的密钥,然后使用forEach()分配缺少的密钥:

const dataSet = [
  {"type": "test", "info": "a lot", "value": 7},
  {"value": 5},
  {"context": "demo", "info": "very long", "value": 3},
  {"info": "no way"}
];

const keys = new Set(dataSet.flatMap(Object.keys));

dataSet.forEach((v) => keys.forEach((k) => v[k] = k in v ? v[k] : false));

console.log(dataSet);


为了解决键顺序相同的额外要求,请注意,历史上,JavaScript对象属性是无序的,因此依赖JavaScript中对象属性的顺序几乎从来都不是一个好主意.

尽管如此,在修改现有对象时很难获得固定的顺序,但如果创建新对象,则是可行的:

const dataSet = [
  {"type": "test", "info": "a lot", "value": 7},
  {"value": 5},
  {"context": "demo", "info": "very long", "value": 3},
  {"info": "no way"}
];

const keys = [...new Set(dataSet.flatMap(Object.keys))];

const result = dataSet.map((v) => keys.reduce((a, k) => ({
  ...a,
  [k]: k in v ? v[k] : false
}), {}));

console.log(result);

Javascript相关问答推荐

如何为GrapesJS模板编辑器创建自定义撤销/重复按钮?

微软Edge Select 间隙鼠标退出问题

深嵌套的ng-container元素仍然可以在Angular 布局组件中正确渲染内容吗?

微软Edge编辑和重新发送未显示""

如何在Connect 4游戏中 for each 玩家使用位板寻找7形状?

Angular 17—每当一个布尔变量变为真时触发循环轮询,只要它保持为真

为什么当我解析一个promise时,输出处于挂起状态?

在带有背景图像和圆形的div中添加长方体阴影时的重影线

使用Google API无法进行Web抓取

在WordPress中使用带有WPCode的Java代码片段时出现意外令牌错误

在HTML语言中调用外部JavaScript文件中的函数

为什么这个.add.group({})在教程中运行得很好,但在我的游戏中就不行了?

在开发期间,Web浏览器如何运行&qot;.jsx&qot;文件?

当标题被点击时,如何使内容出现在另一个div上?

未捕获语法错误:Hello World中的令牌无效或意外

如何使用Cypress在IFRAME中打字

使用Library chart.js在一个带有两个y轴的图表中绘制两个数据集

如何为两条动态路由创建一个页面?

从客户端更新MongoDB数据库

2.0.0-dev quill拖动文本不起作用如何使其拖动文本