Combine array of objects (build details) into a single object (having build names as a top-level keys)

Viewed 48

I am new to javascript and json. I am having an array of objects like below,

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"
      }
   }
];

I am looping this to create a object like below, Expected Output:

 {
   "build":{
      "name1":{
         "type":"element",
         "info":{
            "element":"testvalue",
            "repository":"mag",
            "version":123
         }
      },
      "name2":{
         "type":"element",
         "info":{
            "element":"abcd",
            "repository":"uuuuu",
            "version":"ttttt"
         }
      }
   }
}

But I am getting some invalid format. I tried the below method to make it work but no luck,

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);

Is there anyway to achieve this? Any help would be most appreciated.

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 Answers

You may get the job done by passing respective properties to 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%;}

Or, use 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%;}

Related