Home > Mobile >  How to create an array of merged items from 2 corresponding items, each from another additional arra
How to create an array of merged items from 2 corresponding items, each from another additional arra

Time:05-26

I've converted CSV based text files to arrays containing headers and rows, and now I want to convert them into the below given solution. Can anybody do this using methods like map, reduce or whatever.

The arrays I have are:

let header = ['a', 'b', 'c', 'd'];
let rows = ['1,2,3,4', '5,6,7,8', '9,0,1,2'];

The result I want is:

[{
  a: 1,
  b: 2,
  c: 3,
  d: 4,
}, {
  a: 5,
  b: 6,
  c: 7,
  d: 8,
}, {
  a: 9,
  b: 0,
  c: 1,
  d: 2,
}]

I was able to do this using for loop but that wasn't the appropriate solution for es6.

Above I've mentioned some dummy arrays, right now the actual code is:

const recordReader = content => {
  let weatherRecords = [];
  let rows = content.split('\n');
  let headers = rows.shift().split(',');

  for (let row = 0; row < rows.length; row  ) {
    let weatherReading = {};
    if (!rows[row]) {
      continue;
    }
    let record = rows[row].split(',');
  
    for (let column = 0; column < headers.length; column  ) {
      weatherReading[headers[column]] = record[column];
    }
    weatherRecords.push(weatherReading);
  }
  return weatherRecords;
};

CodePudding user response:

You could map the rows and reduce the row into an object:

const header = ['a', 'b', 'c', 'd'];
const rows = ['1,2,3,4', '5,6,7,8', '9,0,1,2'];

const result = rows.map((row) =>
  row.split(',').reduce(
    (obj, cell, i) => ({
      ...obj,
      [header[i]]: Number(cell),
    }),
    {}
  )
);

console.log(result)

CodePudding user response:

with a combination of map and reduce:

const header = ['a', 'b', 'c', 'd'];
const rows = ['1,2,3,4', '5,6,7,8', '9,0,1,2'];

const res = rows.map(row => {
  const columns = row.split(',');
  return columns.reduce( (acc,cur,i) => ({...acc,[header[i]]:cur}) , {})
  }
);

console.log(res);

This admits a one-liner but i reckon is not very clear to see what it does:

const header = ['a', 'b', 'c', 'd'];
const rows = ['1,2,3,4', '5,6,7,8', '9,0,1,2'];

const res = rows.map(row => row.split(',').reduce( (acc,cur,i) => ({...acc,[header[i]]:cur}) , {}));

console.log(res);

CodePudding user response:

You can .map() your rows elements to objects. To create the object, you can grab the string of numbers, and split them into an array, which you then use .map() on to grab the number values and the associated header from headers using the index of the current number (i). By putting these into a [key, value] pair array, you can call Object.fromEntries() on it to build your object. The below also uses the unary plus operator ( ) to convert your string digit to a number:

const header = ['a', 'b', 'c', 'd'];
const rows = ['1,2,3,4', '5,6,7,8', '9,0,1,2'];

const res = rows.map(item =>
  Object.fromEntries(item.split(',').map((n, i) => [header[i],  n]))
);

console.log(res);

Note, the above uses Object.fromEntries() which was introduced after ES6, you can use Object.assign() for a smilar approach, which is ES6:

const header = ['a', 'b', 'c', 'd'];
const rows = ['1,2,3,4', '5,6,7,8', '9,0,1,2'];

const res = rows.map(item =>
  Object.assign({}, ...item.split(',').map((n, i) => ({[header[i]]:  n})))
);

console.log(res);

CodePudding user response:

Try this code

let header = ['a', 'b', 'c', 'd'];
let rows = ['1,2,3,4', '5,6,7,8', '9,0,1,2'];

let result = rows.map((x) => {
    let elementArr = x.split(',');
    let response = [];
    header.forEach((item,i) => {
        response[item] = parseInt(elementArr[i])
    });
    
    return {...response};
});
console.log(result)

CodePudding user response:

try this

 let header = ['a', 'b', 'c', 'd'];
 let rows = ['1,2,3,4', '5,6,7,8', '9,0,1,2'];
 result=[]
rows.forEach(e=>{
    let a={};
     let i=0;
header.forEach((h)=>{
    a[h]=e.split(',')[i  ]
 });
  result.push(a)
  });

CodePudding user response:

A nested reduce based approach will do the job.

One iterates the rows-array with the outer reducer-function which again iterates each column-value (derived from each splitted row) by a second reduce-task which assigns a column-value to a column-key where each key is derived from the additionally passed header-array and the current inner iteration's column-index.

function rowwiseAssignColumValuesToHeaderColumnKeys({ header, result }, row) {
  result
    .push(
      row
        .split(',')
        .reduce((rowItem, columnValue, columnIndex) =>
          Object.assign(rowItem, {

            [ header[columnIndex] ]: Number(columnValue.trim())

          }), {} // to be aggregated `rowItem` passed as initial value.
        )
    );
  return { header, result };
}
console.log(
  ['1,2,3,4', '5, 6, 7, 8', '9,0,1,2']
    .reduce(
      rowwiseAssignColumValuesToHeaderColumnKeys, {
        header: ['a', 'b', 'c', 'd'],
        result: [],
      },
    ).result
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

  • Related