Nikhil Bharadwaj
Nikhil Bharadwaj

Reputation: 917

How to convert object key value pair with array as values to multi objects of key value pair?

I have an object with key-value pair and its value as an array of elements.

{
    status: ["new", "old"],
    place: ["york", "blah"]
}

I'm trying to convert it into multiple array objects of key-value pair like below.

{

"newObj1": [
      { "status": "new" },
      { "status": "old" }],
"newObj2": [
      { "place": "york" },
      { "place": "blah" }]
}

Is there any way to achieve the above structure? I have tried couple of methods using array reduce methods but it doesn't give in the desired output.

let value= {
        status: ["new", "old"],
        place: ["york", "blah"]
    }
Object.keys(value).map((key) => [key, value[key]]);

Upvotes: 0

Views: 596

Answers (6)

jaimish11
jaimish11

Reputation: 564

For those who fail to understand map and reduce, here's a fairly naive solution but it will work:

newObjCounter = 1
orig = { status: [ 'new', 'old' ], place: [ 'york', 'blah' ] }
newObject = {}

//Initialise object with new keys with arrays as values
for(var key in orig){
    newObject["newObj"+initialCounter] = []
    initialCounter++
}

//Loop through keys of the original object and dynamically populate the new object
for(var key in orig){
    index = "newObj"+objCounter
    newObject[index].push({[key]:orig[key]})
    objCounter++
}

console.log(newObject)

Upvotes: 0

GirkovArpa
GirkovArpa

Reputation: 4912

Here's an idiomatic solution using .reduce inside .reduce:

Object.entries(data)
  .reduce((result, [key, value], index) => !(result['newObj' + (index + 1)] = value
    .reduce((arr, text) => !arr
      .push({ [key]: text }) || arr, [])) || result, {});

Here's a live example:

const data = {
  status: ['new', 'old'],
  place: ['york', 'blah']
};

const result = Object.entries(data)
  .reduce((result, [key, value], index) => !(result['newObj' + (index + 1)] = value
    .reduce((arr, text) => !arr
      .push({ [key]: text }) || arr, [])) || result, {});
      
console.log(result);

/*
{
  newObj1: [
    { status: 'new' },
    { status: 'old' }
  ],
  newObj2: [
    { place: 'york' },
    { place: 'blah' }
  ]
}
*/

Upvotes: 0

Sivakumar Tadisetti
Sivakumar Tadisetti

Reputation: 5041

const data = {
    status: ["new", "old"],
    place: ["york", "blah"]
};

let result = Object.fromEntries( Object.entries(data).map( ([key, [first, second]], index) => {
  return [ `newObj${index}`, [ { [key]: first }, { [key]: second } ] ];
} ) );

console.log(result);

Upvotes: 0

Ahmad
Ahmad

Reputation: 12737

Here is my way of accomplishing that.

let source = {
  status: ["new", "old"],
  place: ["york", "blah"]
};

let destination = {};  // make room for the destinoation object

Object.keys(source).forEach((key, index) => {

  let obj = "newObj" + (index + 1);  // assume all objects are named "newObj1,2,3,etc"
  
  if (!destination[obj]) {  // check if the object exists already
    // if not, then crate an empty array first
    destination[obj] = [];
  }
  
  // loop through all items in the source element array
  source[key].forEach(value => {
    // create an object from the array element
    let subObj = {};
    subObj[key] = value;
    
    // push that object to the destination
    destination[obj].push(subObj);
  });

});

console.log(destination);

Upvotes: 0

uminder
uminder

Reputation: 26150

Here's a solution that uses Array.reduce():

const value = {
  status: ["new", "old"],
  place: ["york", "blah"]
};

const result = Object.keys(value).reduce((acc, key, i) => {
  acc["newObj" + (i + 1)] = value[key].map(k => ({ [key]: k }));
  return acc;
}, {});
console.log(result);

Upvotes: 0

Abito Prakash
Abito Prakash

Reputation: 4770

You can do something like this

const obj = {
    status: ["new", "old"],
    place: ["york", "blah"]
};

const result = {};
Object.keys(obj).forEach((key, index) => {
    result[`newObj${index + 1}`] = obj[key].map(item => ({[key]: item}));
});
console.log(result);

Upvotes: 1

Related Questions