简体   繁体   中英

Turn keys and values of an object into array of objects

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, ie 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

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%;}

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

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM