Javascript. How do you make a loop that creates objects, then those objects being pushed into an array?

Viewed 70

So I started with importing 4 different arrays with equal amounts of data.

Then I made a class, thinking the class can help me make the objects, with that imported data.

So my thinking was if I loop through that class, it can make an object that contains the data of all 4 arrays by its index, and then push that object into an array.

I was hoping my ending results for objectArray would look like...

[ {nn: "Lion", dat1: 4, dat2: 9, dat3: 10}, {nn: "Zebra", dat1: 5, dat2: 10, dat3: 7}, {nn: "Monkey", dat1: 2, dat2: 6, dat3: 14} ...etc. ]

// mock
const threeToType = {
   name: ["Lion", "Zebra", "Monkey"],
  data1: [     4,       5,        2],
  data2: [     9,      10,        6],
  data3: [    10,       7,       14],
};

const {name, data1, data2, data3} = threeToType; // require('./threeToType');

let objectArray = [];

class makeObj{
    constructor(nn, dat1, dat2, dat3){
        this._nn = nn;
        this._dat1 = dat1;
        this._dat2 = dat2;
        this._dat3 = dat3;
    }
}

for(let newObj, i = 0, tN = "", tD1 = 0, tD2 = 0, tD3 = 0; i<name.length; i++){

    tN = name[i];
    tD1 = data1[i];
    tD2 = data2[i];
    tD3 = data3[i];

    objectArray.push(newObj = new makeObj(tN, tD1, tD2, tD3));

}

console.log(objectArray);

4 Answers

Why not just simply:

const {name, data1, data2, data3} = require('./threeToType');
let objectArray = []
for (let i = 0; i < name.length; i++) {
  let newItem = { nn: name[i], tD1: data1[i], tD2: data2[i], td3: data3[i] }
  objectArray.push(newItem)
}

Get your nameArr, data1Arr, data2Arr, and data3Arr from/how you wish - I've used some data for the snippet.

map iterates items in Array (cv here, unused) with their index (idx here).
We use that idx to retrieve "parallel" items from all arrays and make an object out of them.
We surroung the object with parentheses (( and )) because it is returned, and we don't want the browser to think it's code (return is a function, but we're allowed to omit the parentheses, here - we use them).

nameArr=["Zebra", "Lion", "Elephant"];
data1Arr=[23, 12, 40];
data2Arr=["Africa", "America", "India"];
data3Arr=[true, false, true];

objArr=nameArr.map((cv, idx)=>({
  name:nameArr[idx],
  data1:data1Arr[idx],
  data2:data2Arr[idx],
  data3:data3Arr[idx]
}));

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

Here's a more generic solution, that assumes your input arrays are basically rows of a table (since they all have the same length), and you want to "flip" or invert them into columns. A two-dimensional array basically.

I'd keep the names of the input arrays out of this algorithm. There's no easy way to get the name of a variable (like "data1" in your snippet) as a string in JS.

You can call this with any number of arrays btw, as long as they all have the same length.

const invertRows = (...rows) => {
    const numRows = rows.length;
    const numColumns = rows[0].length;

    const inverted = new Array(numColumns);
    for (let col=0; col < numColumns; col++) {
        inverted[col] = new Array(numRows);
        for (let row=0; row < numRows; row++) {
            inverted[col][row] = rows[row][col];
        }
    }
    return inverted;
};

const arr1 = [1,2,3];
const arr2 = [3,4,5];

console.log(invertRows(arr1, arr2));

// Returns: [ [ 1, 3 ], [ 2, 4 ], [ 3, 5 ] ]

I'm currently not really sure what you are asking, your current solution does work.

Here is a general purpose solution that transforms the data structure:

// from
const columns = {name: ["John Doe", "Jane Doe"], age: [42, 39]};
// into
const rows = [{name: "John Doe", age: 42}, {name: "Jane Doe", age: 39}];
// and the other way around.

const threeToType = {
   name: ["Lion", "Zebra", "Monkey"],
  data1: [     4,       5,        2],
  data2: [     9,      10,        6],
  data3: [    10,       7,       14],
};

function columnsToRows(columns) {
  columns = Object.entries(columns);
  if (columns.length == 0) return [];
  
  const colLengths = columns.map(([,values]) => values.length);
  const maxColLength = Math.max(...colLengths);
  
  return Array.from({length: maxColLength}, (_, i) => {
    const row = Object.create(null);
    columns.forEach(([colName, values]) => row[colName] = values[i]);
    return row;
  });
}

function rowsToColumns(rows) {
  if (rows.length == 0) return {};
  const columns = Object.create(null);
  const colNames = new Set(rows.flatMap((row) => Object.keys(row)));
  
  colNames.forEach((colName) => columns[colName] = []);
  rows.forEach((row) => {
    colNames.forEach((colName) => columns[colName].push(row[colName]));
  });
  
  return columns;
}

console.log(columnsToRows(threeToType));
console.log(rowsToColumns(columnsToRows(threeToType)));

Related