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