如何将 For 循环转换为 Reduce 检查名称和求和行?

How to transform a For Loop into Reduce checking names and sum rows?

给定以下数组,我需要将其减去员工函数名称并对几行求和。

如果 Row[1] 与任何其他行相等,则减少,并对 Row[2] 和 Row[5] 求和。

示例数组

[ 
  [ 20, 'AJUDANTE GERAL ', 2, 'HH', 6.36, 12.72, '', '' ],
  [ 20, 'AJUDANTE GERAL ', 8, 'HH', 6.36, 50.88, '', '' ],
  [ 20, 'AJUDANTE GERAL ', 0.15, 'HH', 6.36, 0.954, '', '' ],
  [ 20, 'AJUDANTE GERAL ', 8, 'HH', 6.36, 50.88, '', '' ],
  [ 125, 'CALDEREIRO', 8, 'HH', 13.05, 104.4, '', '' ],
  [ 0, 'ISOLADOR', 2, 'HH', 10.68, 21.36, '', '' ],
  [ 0, 'ISOLADOR', 8, 'HH', 10.68, 85.44, '', '' ],
  [ 0, 'ISOLADOR', 0.15, 'HH', 10.68, 1.6019999999999999, '', '' ],
  [ 585, 'PINTOR', 2, 'HH', 10.91, 21.82, '', '' ] 
]

预期结果

[
  [ 20, 'AJUDANTE GERAL ', 18.15, 'HH', 6.36, 115.434, '', '' ],
  [ 125, 'CALDEREIRO', 8, 'HH', 13.05, 104.4, '', '' ],
  [ 0, 'ISOLADOR', 10.15, 'HH', 10.68, 108.402, '', '' ],
  [ 585, 'PINTOR', 2, 'HH', 10.91, 21.82, '', '' ]
]

我能够使用一些 for loops 实现此目的,但我认为这不是真正的交易,因为我在循环期间更改值。它正在工作,但是,我想了解我如何使用 reduce 和 maps 来做到这一点。

// sheetMapped is the array with all data duplicated
// uniqueRows is where I am keeping only the unique values with the sum values

let uniqueRows = [];
for (let i = 0; i < sheetMapped.length; i += 1) {
  let row = sheetMapped[i];
  let found = false;

  for (let j = 0; j < uniqueRows.length; j += 1) {
    let rowUniqueTest = uniqueRows[j];

    if (row[1] === rowUniqueTest[1]) {
      found = true;
      uniqueRows[j][2] += row[2];
      uniqueRows[j][5] += row[5];
      break;
    }
  }
  if (!found) {
    uniqueRows.push(row);
  }
}

我已经使用 Array.fromset Mapsreduces 尝试了一些示例,但它们有点难以理解,因为我正在处理数组中的更多数据,而不仅仅是key/value pairs.

提前致谢

这可以通过使用 reduce().

的相当标准的 'group by' 操作来完成

下面的代码片段使用 Map,因为它维护插入顺序,其中对象对数字属性进行排序。使用 Array.from() called on the Map.values()

将生成的 Map 转换回数组

const input = [ [ 20, 'AJUDANTE GERAL ', 2, 'HH', 6.36, 12.72, '', '' ], [ 20, 'AJUDANTE GERAL ', 8, 'HH', 6.36, 50.88, '', '' ], [ 20, 'AJUDANTE GERAL ', 0.15, 'HH', 6.36, 0.954, '', '' ], [ 20, 'AJUDANTE GERAL ', 8, 'HH', 6.36, 50.88, '', '' ], [ 125, 'CALDEREIRO', 8, 'HH', 13.05, 104.4, '', '' ], [ 0, 'ISOLADOR', 2, 'HH', 10.68, 21.36, '', '' ], [ 0, 'ISOLADOR', 8, 'HH', 10.68, 85.44, '', '' ], [ 0, 'ISOLADOR', 0.15, 'HH', 10.68, 1.6019999999999999, '', '' ], [ 585, 'PINTOR', 2, 'HH', 10.91, 21.82, '', '' ], ];

const result = Array.from(
  input
    .reduce((a, row) => {
      if (!a.has(row[1])) {
        a.set(row[1], [...row]);
      } else {
        const _row = a.get(row[1]);
        _row[2] += row[2];
        _row[5] += row[5];
      }

      return a;
    }, new Map())
    .values()
);

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

reduce 中使用数组作为累加器这是小菜一碟,看看下面的代码

var data = [ 
    [ 20, 'AJUDANTE GERAL ', 2, 'HH', 6.36, 12.72, '', '' ],
    [ 20, 'AJUDANTE GERAL ', 8, 'HH', 6.36, 50.88, '', '' ],
    [ 20, 'AJUDANTE GERAL ', 0.15, 'HH', 6.36, 0.954, '', '' ],
    [ 20, 'AJUDANTE GERAL ', 8, 'HH', 6.36, 50.88, '', '' ],
    [ 125, 'CALDEREIRO', 8, 'HH', 13.05, 104.4, '', '' ],
    [ 0, 'ISOLADOR', 2, 'HH', 10.68, 21.36, '', '' ],
    [ 0, 'ISOLADOR', 8, 'HH', 10.68, 85.44, '', '' ],
    [ 0, 'ISOLADOR', 0.15, 'HH', 10.68, 1.6019999999999999, '', '' ],
    [ 585, 'PINTOR', 2, 'HH', 10.91, 21.82, '', '' ] 
]



data = data.reduce((a,e)=>{
        let sInd = a.findIndex(each=>each.indexOf(e[1]) != -1)
        if(sInd >= 0){ // if entry added already
            a[sInd][2] += e[2]
            a[sInd][5] += e[5]
        }
        else{a.push(e)} // if new entry
        return a
    },[])

console.log(data.join("\n"))

如果行和列是固定的,您可以使用下面的示例代码。合并为一个对象并获取所有值。

const data = [
  [20, "AJUDANTE GERAL ", 2, "HH", 6.36, 12.72, "", ""],[20, "AJUDANTE GERAL ", 8, "HH", 6.36, 50.88, "", ""],[20, "AJUDANTE GERAL ", 0.15, "HH", 6.36, 0.954, "", ""],[20, "AJUDANTE GERAL ", 8, "HH", 6.36, 50.88, "", ""],
  [125, "CALDEREIRO", 8, "HH", 13.05, 104.4, "", ""],
  [0, "ISOLADOR", 2, "HH", 10.68, 21.36, "", ""],[0, "ISOLADOR", 8, "HH", 10.68, 85.44, "", ""],[0, "ISOLADOR", 0.15, "HH", 10.68, 1.6019999999999999, "", ""],[585, "PINTOR", 2, "HH", 10.91, 21.82, "", ""],
];

const map = data.reduce((m, row) => {
  const id = row[0];
  if (id in m) {
    m[id][2] += row[2];
    m[id][5] += row[5];
  } else {
    m[id] = row;
  }
  return m;
}, {});

console.log(Object.values(map));