1

So I have an array of arrays which are rows in a table and I'd like to convert that to an array of objects. I have a columns array so I know what the keys will be, and of course the length is obviously the same. I know how to do this traditionally with a for loop, but was wondering how to do this with reduce or possible another more succinct way.

let columnArr = ["Name", "Group", "Tier"];

let twoDArryOfArrs = [
  ["Fred", "1FAKnock", "1a"],
  ["Brenda", "2GPvoge", "1a"],
  ["Francis", "67Gruz", "1a"],
  ["Arnold", "1FAKnock", "2b"],
  ["Candice", "67Gruz", "1a"],
  ["Larry", "1GTAFQT", "4a"],
  ["Tony", "2GPvoge", "2c"],
  ["Ronnie", "2GPvoge", "3a"]
];

function convert2dArryToArrOfObjects(arr2d, colArr) {
  let obj = {},
      resultArr = [];
  for (let i = 0; i < arr2d.length; i++) {
    let innerArr = arr2d[i];
    for (let j = 0; j < innerArr.length; j++) {
      obj[colArr[j]] = innerArr[j];
    }
    resultArr.push(obj);
    obj = {};
  }
  return resultArr;
}

const output = convert2dArryToArrOfObjects(twoDArryOfArrs, columnArr);

console.log(output);

3 Answers 3

1

One approach would be to nest a reduction inside of a reduction, where:

  • the outer reduction is concerned with obtaining the desired resultArr and
  • the inner reduction focuses on composing the "per-row" item object that matches columns to row values

As mentioned, the assumption is that the number of columns matches the number of row items in your input 2D array - with that in mind, the following solution should achieve what you require:

let columnArr = ["Name", "Group", "Tier"];

let twoDArryOfArrs = [
  ["Fred", "1FAKnock", "1a"],
  ["Brenda", "2GPvoge", "1a"],
  ["Francis", "67Gruz", "1a"],
  ["Arnold", "1FAKnock", "2b"],
  ["Candice", "67Gruz", "1a"],
  ["Larry", "1GTAFQT", "4a"],
  ["Tony", "2GPvoge", "2c"],
  ["Ronnie", "2GPvoge", "3a"]
];

// Cause the resulting array to be logged to console (for snippet)
console.log(twoDArryOfArrs.reduce((resultArr, row, idx) => {

  // Extract item object for result array from current row via
  // a nested reduction
  const item = columnArr.reduce((obj, col, jdx) => {

    // Compose the object by merging row value (at ordered jdx)
    // to "col" key of current column, into the resulting object
    // item
    return { ...obj,
      [col]: row[jdx]
    }

  }, {})

  //Append the composed item object to the current resultArr that
  // has been reduced
  return [...resultArr, item]
}, []))

Hope that helps!

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

Comments

0

you can do it with map this way

let columnArr = ["Name", "Group", "Tier"];

let twoDArryOfArrs = [
  ["Fred", "1FAKnock", "1a"],
  ["Brenda", "2GPvoge", "1a"],
  ["Francis", "67Gruz", "1a"],
  ["Arnold", "1FAKnock", "2b"],
  ["Candice", "67Gruz", "1a"],
  ["Larry", "1GTAFQT", "4a"],
  ["Tony", "2GPvoge", "2c"],
  ["Ronnie", "2GPvoge", "3a"]
];

let arrayOfObj = twoDArryOfArrs.map( el => ({Name: el[0], Group: el[1], Tier:el[2]}))
console.log(arrayOfObj)

Comments

0

You don't need reduce, just a simple map:

conv2 = (a2, cols) => a2.map(el => ({
  [cols[0]]: el[0],
  [cols[1]]: el[1],
  [cols[2]]: el[2]
}));

Comments

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.