我有以下代码可以正常工作。 我只是想知道是否有更优雅/更优化的方式。
长“代码”简短,给出数据:
var myArray = [
['X', 'A', 0, 1, 'Y', 3],
['X', 'A', 4, 5, 'Y', 6],
['X', 'B', 6, 5, 'Y', 4],
['X', 'B', 3, 2, 'Y', 1],
['X', 'C', 7, 8, 'Y', 9],
];
假设我想按列索引1
进行分组,只对列索引2, 3, 5
求和。
预期结果是:
[
["A", 4, 6, 9],
["B", 9, 7, 5],
["C", 7, 8, 9]
]
// data
var myArray = [
['X', 'A', 0, 1, 'Y', 3],
['X', 'A', 4, 5, 'Y', 6],
['X', 'B', 6, 5, 'Y', 4],
['X', 'B', 3, 2, 'Y', 1],
['X', 'C', 7, 8, 'Y', 9],
];
// col that I want to group by
var colIndex = 1;
// cols I want to sum
var colsToSum = [2, 3, 5];
var arrayGroupBy = function(myArray, colIndex, colsToSum) {
// get unique column values
var uniqueValues = [];
myArray.forEach(function(row) {
if (uniqueValues.indexOf(row[colIndex]) === -1) {
uniqueValues.push(row[colIndex]);
}
});
var newData = [];
uniqueValues.forEach(function(value) {
// get filtered rows
var filteredRows = myArray.filter(function(row) {
return row[colIndex] === value;
});
var row = [value];
// columns to sum
colsToSum.forEach(function(num) {
if (filteredRows.length === 1) {
// push single row
row.push(filteredRows[0][num]);
} else {
// sum row cols
var total = filteredRows.reduce(function(sum, current) {
return sum + current[num];
}, 0);
row.push(total);
}
});
newData.push(row);
});
return newData;
};
console.log(arrayGroupBy(myArray, colIndex, colsToSum));
不幸的是我不能在这个上使用ES6 ......
谢谢!
答案 0 :(得分:0)
我试图为您的问题找到解决方案。将有许多优秀的ES6功能可以使解决方案更具可读性/更清晰。但这是一个没有任何ES6功能的解决方案:
var groupBy = function(myArray, colIndex, colsToSum) {
var obj = {};
myArray.forEach(function(e) {
if(!obj.hasOwnProperty(e)) {
obj[e[colIndex]] = new Array(colsToSum.length + 1)
.join('0').split('').map(parseFloat);
}
});
myArray.forEach(function(row) {
for (var i = 0; i < colsToSum.length; i++) {
obj[row[colIndex]][i] += row[colsToSum[i]];
}
});
return Object.keys(obj).map(function(key) {
return [key].concat(obj[key]);
});
}
说明:
[0, 0, 0]
将分配给每个媒体资源。myArray
和colsToSum
并将值添加到正确的对象属性也许有更好的解决方案:)