JS,数组对象统计的方法(最大值、最小值、平均值)
最近强迫症越来越严重,已经忘记了“能跑就行”的原则,总是追求改进,折腾自己。现在我们有一组数据,需求是对列进行计算,并添加两行,分别是最大值、最小值。
通过以下方法,功能已经实现。
但还是感觉代码太冗长,不利于维护和复用。
请各位大佬指教,有没有更简洁,和方便复用的写法,例如要增加最大值、最小值、平均值三行。有什么好的实现方法,欢迎交流、指正。感谢。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 原数据
const arrData = [
{
"col0": "2022/10/5",
"col1": 0.80,
"col2": 0.92,
"col3": 0.33
}, {
"col0": "2022/10/6",
"col1": 0.86,
"col2": 0.63,
"col3": 0.68
}, {
"col0": "2022/10/7",
"col1": 0.83,
"col2": 0.89,
"col3": 0.62
}
];
// 先打印看看原数据
console.table(arrData);
// 获得对象的key
const arrKeys = Object.keys(arrData);
// =====最大值=====
// 获得最大值(数组)
let arrMax = arrKeys.map((key, index) => {
let arr = [];
arrData.forEach(row => {
arr.push(row)
});
return index ? Math.max(...arr) : '最大值'
});
// 转回对象
let objMax = {};
arrKeys.forEach((key, index) => {
objMax = arrMax
});
// 添加到原数据中
arrData.push(objMax)
// =====最小值=====
// 获得最小值(数组)
let arrMin = arrKeys.map((key, index) => {
let arr = [];
arrData.forEach(row => {
arr.push(row)
});
return index ? Math.min(...arr) : '最大值'
});
// 转回对象
let objMin = {};
arrKeys.forEach((key, index) => {
objMin = arrMin
});
// 添加到原数据中
arrData.push(objMin)
// 打印结果
console.table(arrData);
</script>
</body>
</html> 我也有点强迫症 好烦 {:301_973:}{:301_980:}{:301_972:} 凡是有重复出现的代码,就把这段代码提取成一个函数,给出不同的参数,从而得到不同的结果。 // 最大值
const maxValue = arrData.reduce((preValue, current) => Math.max(preValue, current.col1).toFixed(2), 0)
// 最小值
const minValue = arrData.reduce((preValue, current) => Math.min(preValue, current.col1).toFixed(2), 1)
// 求和以col1为例
const countCol1 = arrData.reduce((preValue, current) => preValue += current.col1,0) 自己研究了一下,好像这个比较符合自己的需求。
// 最大值
const maxValue = (arr) => {
// 首先根据数组的第一个对象,生成一个空的对象
let obj = { ...arr };
Object.keys(arr).forEach((key, index) => {
obj = index ? '' : '最大值'
});
// 通过累加器返回最大值
return arr.reduce((pre, cur) => {
for (const key in pre) {
pre = pre && typeof pre === "number" ? Math.max(pre, cur) : pre ? pre : cur
}
return pre
}, obj)
}
console.log('maxValue', maxValue(arrData))
// {col0: '最大值', col1: 0.86, col2: 0.92, col3: 0.68} 稍微修改了以下,支持数组对象直接添加最大值、最小值的行。
// 原数据
const arrData = [
{
"col0": "2022/10/5",
"col1": 0.80,
"col2": 0.92,
"col3": 0.33
}, {
"col0": "2022/10/6",
"col1": 0.86,
"col2": 0.63,
"col3": 0.68
}, {
"col0": "2022/10/7",
"col1": 0.83,
"col2": 0.89,
"col3": 0.62
}
];
// 先打印看看原数据
console.table(arrData);
// 获得最大值或最小值
const pushMaxOrMin = (arr,isMax) => {
// 首先根据数组的第一个对象,生成一个空的对象
const obj = { ...arr };
Object.keys(arr).forEach((key, index) => {
obj = index ? '' : isMax?'最大值':'最小值'
});
// 通过累加器计算
const res = arr.reduce((pre, cur) => {
for (const key in pre) {
pre = pre && typeof pre === "number" ? isMax?Math.max(pre, cur):Math.min(pre, cur) : pre ? pre : cur
}
return pre
}, obj)
// 添加到原数组
arr.push(res)
}
// 添加最大值行
pushMaxOrMin(arrData,1)
// 添加最小值行
pushMaxOrMin(arrData,0)
console.table(arrData) 我觉得从最大值, 最小值等等方法剥离出来一个抽象的逻辑要好一点, 你这个一堆三元运算符挤在一起看着不头疼吗? 我反正是看都不愿看.
既然是对列作运算, 我的思路是先写一个列选择器, 返回指定列的数据, 这样不仅是求最大值, 求最小值, 以后要是有新的计算, 比如求平均值等等, 这个都可以复用.
// 原数据
const arrData = [
{
"col0": "2022/10/5",
"col1": 0.80,
"col2": 0.92,
"col3": 0.33
}, {
"col0": "2022/10/6",
"col1": 0.86,
"col2": 0.63,
"col3": 0.68
}, {
"col0": "2022/10/7",
"col1": 0.83,
"col2": 0.89,
"col3": 0.62
}
];
const memo = {}; // 存放已经选择过的列, 再次选择同样的列时不用再跑循环, 直接查
let selectCol = (data, colKey) => {
if (memo) return memo;
let col = [];
data.forEach( element => {
col.push(element);
})
memo = col;
return col;
}
// 获得对象的key
const colKeys = Object.keys(arrData);
let maxRow = {}, minRow = {};
colKeys.forEach( (colKey, index) => {
if (!index) {
maxRow = "最大值";
minRow = "最小值";
}
else {
maxRow = Math.max(...selectCol(arrData, colKey));
minRow = Math.min(...selectCol(arrData, colKey));
}
})
console.table([...arrData, maxRow, minRow]);
页:
[1]