0
let response = {
    data1: {
       names: ["John", "jim"]
    },
    data2: {
       ages: [34, 24]
    }
}

I want:

data: {
   names: ["John", "jim"],
   ages: [34,24]
}

Is there a way to merge these into 1 object without referencing response.data1 and response.data2? I know I can do const newObj = {...response.data1, ...response.data2} or Object.assign({}, response.data1, response.data1)... Can I do via a for in loop?

Dave Newton
  • 158,873
  • 26
  • 254
  • 302

2 Answers2

2

You could merge the values of the object using Object.assign() like this:

Object.assign({}, ...Object.values(response))

Explanation:

This is the syntax for Object.assign: Object.assign(target, source1, source2, ... etc). It basically takes all the properties from the source objects and updates the target object

The Object.values() bit returns the value of the response object. In this case, it's an array of objects like this:

[
  { names: ["John", "jim"] }, 
  { ages: [34, 24] }
]

You can spread the array and pass individual object as a parameter to Object.assign()

Here's a snippet:

let response = {
  data1: {
    names: ["John", "jim"]
  },
  data2: {
    ages: [34, 24]
  }
}

const output = Object.assign({}, ...Object.values(response))

console.log(output)

If it's too confusing you could use reduce:

Object.values(response)
      .reduce((a, v) => ({ ...a, ...v }), {})

Or a simple loop:

const output = {}

for(const key in response)
  Object.assign(output, response[key])
adiga
  • 34,372
  • 9
  • 61
  • 83
  • I believe the question makes note that they are aware of the `Object.assign` solution, but that they specifically want to try to accomplish it with a loop. – Alexander Nied Apr 28 '21 at 15:43
  • @AlexanderNied that's not what they meant. They are saying they don't want to use the property name `data1` explicitly as it is dynamic and there could be unknown number of properties. – adiga Apr 28 '21 at 15:44
  • Ah sure, that's fair; that's probably the correct interpretation. – Alexander Nied Apr 28 '21 at 15:47
  • @AlexanderNied they said they were aware of _an_ `Object.assign` solution. There is no such thing as _the_ `Object.assign` solution. – Richard Dunn Apr 28 '21 at 15:47
1

If you want to merge data1 and data2 using a for in loop, try this:

let response = {
    data1: {
       names: ["John", "jim"]
    },
    data2: {
       ages: [34, 24]
    }
}
var result = {}
for (data in response) {
  if (response.hasOwnProperty(data)) {
    [key] = Object.keys(response[data])
    result[key] = response[data][key]
  }
}
console.log(result)

The way it works is by getting the keys of data and data2, then using those keys, it gets the values and adds it to result

RedYetiDev
  • 404
  • 3
  • 16
  • 1
    Probably worth noting that, because `for...in` loops will go over _all_ properties of an object, including inherited ones, one generally will want to include a [.hasOwnProperty() check](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty) before proceeding with any processing. – Alexander Nied Apr 28 '21 at 15:45
  • I fixed it, is that better? – RedYetiDev Apr 28 '21 at 15:47