将对象数组(构建细节)合并为单个对象(以构建名称作为顶级键)

3

我是javascript和json的新手。我有一个像下面这样的对象数组:

let data = [
   {
      "build_name":"name1",
      "build_type":"element",
      "info":{
         "element":"testvalue",
         "repository":"mag",
         "version":123
      }
   },
   {
      "build_name":"name2",
      "build_type":"element",
      "info":{
         "element":"abcd",
         "repository":"uuuuu",
         "version":"ttttt"
      }
   }
];

我循环创建以下的对象, 期望输出:
 {
   "build":{
      "name1":{
         "type":"element",
         "info":{
            "element":"testvalue",
            "repository":"mag",
            "version":123
         }
      },
      "name2":{
         "type":"element",
         "info":{
            "element":"abcd",
            "repository":"uuuuu",
            "version":"ttttt"
         }
      }
   }
}

但是我得到了一些无效格式的错误。我尝试使用以下方法使其工作,但没有成功,

let test = [];
data.forEach(function (arr) {
let test2 = {
[arr.build_name]: {
    "type": arr.build_type
},
"info": {
"element": arr.info.element,
"repository": arr.info.repository,
"version": arr.info.version
}
}
test.push(test2);
});
console.log(JSON.stringify(test));
let val = 
{"build" : {
test
}
}
console.log(val);

有没有办法实现这个?非常感谢任何帮助。

JSFiddle - https://jsfiddle.net/c9dxjgrt/

let data = [{
    "build_name": "name1",
    "build_type": "element",
    "info": {
      "element": "testvalue",
      "repository": "mag",
      "version": 123
    }
  },
  {
    "build_name": "name2",
    "build_type": "element",
    "info": {
      "element": "abcd",
      "repository": "uuuuu",
      "version": "ttttt"
    }
  }
];
let test = [];
data.forEach(function(arr) {
  let test2 = {
    [arr.build_name]: {
      "type": arr.build_type
    },
    "info": {
      "element": arr.info.element,
      "repository": arr.info.repository,
      "version": arr.info.version
    }
  }
  test.push(test2);
});
console.log(JSON.stringify(test));
let val = {
  "build": {
    test
  }
}

console.log(val);

1个回答

4

您可以通过将相应的属性传递给 Object.assign()来完成工作:

const src = [{"build_name":"name1","build_type":"element","info":{"element":"testvalue","repository":"mag","version":123}},{"build_name":"name2","build_type":"element","info":{"element":"abcd","repository":"uuuuu","version":"ttttt"}}],

      result = {
        build: Object.assign(
          {},
          ...src.map(({build_name,build_type:type, info}) => 
            ({[build_name]:{type, info}}))
        )
      }
      
console.log(result)
.as-console-wrapper{min-height:100%;}

或者使用Array.prototype.reduce()

const src = [{"build_name":"name1","build_type":"element","info":{"element":"testvalue","repository":"mag","version":123}},{"build_name":"name2","build_type":"element","info":{"element":"abcd","repository":"uuuuu","version":"ttttt"}}],

      result = src.reduce(({build},{build_name,build_type:type,info}) =>
        ({build:{...build, [build_name]:{type,info}}}),
        {build:{}})
      
console.log(result)
.as-console-wrapper{min-height:100%;}


我也喜欢那个解决方案。虽然它显然“破坏”了先前存在的build_name的副本,但问题暗示这是可以接受的。 - Arrmaniac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接