如何使用(主要)数组方法从 2 个对应项创建一个合并项数组,每个项都来自另一个附加数组?

How to create an array of merged items from 2 corresponding items, each from another additional array, using (mainly) array methods?

我已经将基于 CSV 的文本文件转换为包含 headers 和行的数组,现在我想将它们转换为下面给出的解决方案。任何人都可以使用 mapreduce 或其他方法来做到这一点。

我有的数组是:

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

我想要的结果是:

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

我能够使用 for 循环来做到这一点,但这不是 es6 的合适解决方案。

上面我提到了一些虚拟数组,现在实际代码是:

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

您可以映射行并将行缩减为一个对象:

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)

您可以.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 (+)将字符串数字转换为数字:

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

注意,上面使用了ES6之后引入的Object.fromEntries(),你可以使用Object.assign()更简单的做法,也就是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);

试试这个代码

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)

结合使用 map 和 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);

这承认了一个 one-liner 但我认为它的作用不是很清楚:

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

试试这个

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

基于嵌套 reduce 的方法可以完成这项工作。

一个用外部 reducer-function 迭代 rows 数组,它再次迭代每个 column-value(从每个 splitted row 派生)第二个 reduce-task 将 column-value 分配给 column-key,其中每个键都来自额外传递的 header-array 和当前内部迭代的 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; }

以上主要基于 reduce 的方法可以重构为 re-usable 映射函数,其中考虑了 the 2nd thisArg parameter of Array.prototype.map

function assignColumValuesAccordingToBoundHeaderColumnKeys(row) {
  const header = this;
  return  row
    .split(',')
    .reduce((rowItem, columnValue, columnIndex) =>
      Object.assign(rowItem, {

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

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