如何将 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.from
、set Maps
、reduces
尝试了一些示例,但它们有点难以理解,因为我正在处理数组中的更多数据,而不仅仅是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));
给定以下数组,我需要将其减去员工函数名称并对几行求和。
如果 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.from
、set Maps
、reduces
尝试了一些示例,但它们有点难以理解,因为我正在处理数组中的更多数据,而不仅仅是key/value pairs
.
提前致谢
这可以通过使用 reduce()
.
下面的代码片段使用 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));