1

I want to convert the below JSON format

let init = {
  test1: [1, 2, 3, 4, 5],
  test2: [6, 7, 8, 9, 10]
}

into this format using javascript native methods of array or object (supported in all browsers)

[{
  test1: 1,
  test2: 6
},{
  test1: 2,
  test2: 7
},{
  test1: 3,
  test2: 8
},{
  test1: 4,
  test2: 9
},{
  test1: 5,
  test2: 10
}]

I have tried with for loop and below is the code,

let keys = Object.keys(init);
let result = [];
for(let i = 0; i < keys.length; i++){
   let key = keys[i];
   for(let j = 0; j < init[key].length; j++){
      if(i === 0){
        let obj1 = {};
        obj1[key] = init[key][j];
        result.push(obj1);
    }else{
        let obj2 = result[j];
        obj2[key] = init[key][j];
    }    
  }
}
3
  • 2
    Can you add what you've tried so far? Thanks! Commented Nov 14, 2019 at 2:09
  • Nick, I have used simply for loop, but I want to do this with javascript native methods and couldn't think any approach on this Commented Nov 14, 2019 at 2:12
  • 1
    @ggorlen I have posted my attempt using for loop. As I am currently new on using JS native methods that's why I have used for loop. For more clarity on grouping logic, I have changed the test2 property value Commented Nov 14, 2019 at 3:29

2 Answers 2

1

You could use Array.prototype.reduce() to do that.

Iterate on test1 array elements and push a new object to the array accumulator with test1 and test2 properties and their respective values.

let init = {
  test1: [1, 2, 3, 4, 5],
  test2: [6, 7, 8, 9, 10]
};

let keys = Object.keys(init);
let key1 = keys[0];
let key2 = keys[1];

let result = init[key1].reduce((acc, curr, i) => {
  acc.push({
    [key1]: curr,
    [key2]: init[key2][i]
  });

  return acc;
}, []);

console.log(result);

As of now, reduce() method is supported in most of the modern browsers. For supporting all browsers, it is better to use for loop, but instead of Object.keys() iterate on object properties or use a polyfill.

let init = {
  test1: [1, 2, 3, 4, 5],
  test2: [6, 7, 8, 9, 10]
};

let keys = [];

for (let key in init) {
  if (init.hasOwnProperty(key)) {
    keys.push(key);
  }
}

let key1 = keys[0];
let key2 = keys[1];

let result = [];

for (let i = 0; i < key1.length; i++) {
  result.push({
    [key1]: init[key1][i],
    [key2]: init[key2][i]
  });
}

console.log(result);

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for answering. Though if I have more than two properties in init object say test1 to testn having the same length of arrays, then I think in reduce function we need to add for loop
That's right @NarenderSaharan — a for loop to iterate on object keys.
1

You could use a combination of for...in and Array.forEach to achieve this result in a few lines of code. If you wan't support for all browsers you can better use var instead of let though. https://caniuse.com/#search=let

var init = {
  test1: [1, 2, 3, 4, 5],
  test2: [6, 7, 8, 9, 10]
}

var result = []
for (var key in init) {
  init[key].forEach(function (item, index) {
    result[index] ? result[index][key] = item : result[index] = { [key]: item }
  })
}

console.log(result)

You could maybe simplify this a bit more by initializing your result with empty objects, that would avoid using a ternary statement. That would look like this:

Disclaimer: This won't work in IE11 because of the lack of Array.fill() support

var init = {
  test1: [1, 2, 3, 4, 5],
  test2: [6, 7, 8, 9, 10]
}

var result = new Array(Object.keys(init)[0].length).fill().map(Object);
for (var key in init) {
  init[key].forEach(function(item, index) {
    result[index][key] = item
  })
}

console.log(result)

If you do this make sure you don't create an array with Objects that are a reference to the same object in memory: Array.prototype.fill() with object passes reference and not new instance

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.