0

so I have a data structure that looks like this :

data = {
  a: [1, 2, 3, 4, 5],
  b: ["a", "b", "c", "d", "e"],
  c: ["123", "235423", "12312", "1231", "12312"],
  d: ["aa", "bb", "cc", "dd", "ee"],
  ...
}

and I need to convert it into a following structure:

[
   { a: 1, b: "a", c: "123", d: "aa", ... },
   { a: 2, b: "b", c: "235423", d: "bb", ... },
   { a: 3, b: "c", c: "12312", d: "cc", ... },
   { a: 4, b: "d", c: "1231", d: "dd", ... },
   { a: 5, b: "a", c: "12312", d: "ee", ... },
]

the number of keys in data can vary, but the length of the values will always be same across all arrays, i.e. data[a].length === data[z].length will always be true.

My solution:

const doStuff = () => {
    const result = [];
    const keys = Object.keys(data);

    if (!keys) return result;

    const valuesLength = keys[0].length
    const result = [];

    for (let i = 0; i < valuesLength ; i++) {
        const obj = {};
        for (const key in data) {
            obj[key] = data[key][i];
        }

        result.push(obj);
    }
    return result;
};

is using two for loops is not most effective one since the number of keys can be large, so i'm looking for a most optimal solution

2
  • 2
    It is going to be two loops. Show your solution. Commented Oct 7, 2020 at 19:25
  • @epascarello updated Commented Oct 7, 2020 at 19:41

4 Answers 4

1

You may traverse your source object keys (Object.keys()) with Array.prototype.reduce(), looping inner arrays with Array.prototype.forEach() and assigning corresponding property of resulting object:

const src = {a:[1,2,3,4,5],b:["a","b","c","d","e"],c:["123","235423","12312","1231","12312"],d:["aa","bb","cc","dd","ee"]},

      result = Object
        .keys(src)
        .reduce((acc, key, i, keys) => {
          src[key].forEach((v, j) => {
            acc[j] = acc[j] || {}
            acc[j][key] = v
          })
          return acc
        }, [])
        
console.log(result)
.as-console-wrapper{min-height:100%;}

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

Comments

0

The solution is going to require two loops. One to go over the properties in the object, the other to loop over the array of values.

Personally I would use reduce and forEach for the two loops

const data = {
  a: [1, 2, 3, 4, 5],
  b: ["a", "b", "c", "d", "e"],
  c: ["123", "235423", "12312", "1231", "12312"],
  d: ["aa", "bb", "cc", "dd", "ee"]
}

const result = Object.entries(data).reduce((arr, [key, values]) => (
  values.forEach((value, index) => {
    arr[index] = {
      ...arr[index],
      [key]: value
    };
  }),
  arr), []);

console.log(result);

without the fat arrows and destructuring

var data = {
  a: [1, 2, 3, 4, 5],
  b: ["a", "b", "c", "d", "e"],
  c: ["123", "235423", "12312", "1231", "12312"],
  d: ["aa", "bb", "cc", "dd", "ee"]
};

var result = Object.entries(data).reduce(function(result, entry) {
  var key = entry[0];
  var arr = entry[1];

  arr.forEach(function(value, index) {
    result[index] = result[index] || {};
    result[index][key] = value;
  });

  return result;
}, []);

console.log(result);

Comments

0

Please check the below code:

var data = {
  a: [1, 2, 3, 4, 5],
  b: ["a", "b", "c", "d", "e"],
  c: ["123", "235423", "12312", "1231", "12312"],
  d: ["aa", "bb", "cc", "dd", "ee"]
}
  
var anotherObjArray = [];

  for(var i=0;i<data[Object.keys(data)[0]].length;i++){
    let tempObj = {};
    for(var j=0;j<Object.keys(data).length;j++){
        tempObj[Object.keys(data)[j]] = data[Object.keys(data)[j]][i];    
    }
    anotherObjArray.push(tempObj);
  }

anotherObjArray is the final array for your requirement.

2 Comments

thats basically the same that i have
@testing_kate Yeah, basically almost same except the inner for loop which I iterated over an array instead of object. Because iterating over array is most preferred one than an object.
0

By assuming same length arrays, you could get the entries and reduce the array by mapping all values along with the object at the same index and the new property.

const
    data = { a: [1, 2, 3, 4, 5], b: ["a", "b", "c", "d", "e"], c: ["123", "235423", "12312", "1231", "12312"], d: ["aa", "bb", "cc", "dd", "ee"] },
    result = Object
        .entries(data)
        .reduce((r, [k, a]) => a.map((v, i) => ({ ...r[i], [k]: v })), []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

1 Comment

right. it need same length arrays, which op is asking for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.