吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1138|回复: 5
收起左侧

[求助] JS,数组对象统计的方法(最大值、最小值、平均值)

[复制链接]
cqwcns 发表于 2022-10-16 12:42
最近强迫症越来越严重,已经忘记了“能跑就行”的原则,总是追求改进,折腾自己。


现在我们有一组数据,需求是对列进行计算,并添加两行,分别是最大值、最小值。
通过以下方法,功能已经实现。
但还是感觉代码太冗长,不利于维护和复用。
请各位大佬指教,有没有更简洁,和方便复用的写法,例如要增加最大值、最小值、平均值三行。有什么好的实现方法,欢迎交流、指正。感谢。

微信图片_20221016123702.png

[JavaScript] 纯文本查看 复制代码
<!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[0]);


        // =====最大值=====
        // 获得最大值(数组)
        let arrMax = arrKeys.map((key, index) => {
            let arr = [];
            arrData.forEach(row => {
                arr.push(row[key])
            });
            return index ? Math.max(...arr) : '最大值'
        });

        // 转回对象
        let objMax = {};
        arrKeys.forEach((key, index) => {
            objMax[key] = arrMax[index]
        });
        // 添加到原数据中
        arrData.push(objMax)

        // =====最小值=====
        // 获得最小值(数组)
        let arrMin = arrKeys.map((key, index) => {
            let arr = [];
            arrData.forEach(row => {
                arr.push(row[key])
            });
            return index ? Math.min(...arr) : '最大值'
        });

        // 转回对象
        let objMin = {};
        arrKeys.forEach((key, index) => {
            objMin[key] = arrMin[index]
        });
        // 添加到原数据中
        arrData.push(objMin)

        // 打印结果
        console.table(arrData);

    </script>
</body>

</html>

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

甜萝 发表于 2022-10-16 13:03
我也有点强迫症 好烦
ligxi 发表于 2022-10-16 14:16
凡是有重复出现的代码,就把这段代码提取成一个函数,给出不同的参数,从而得到不同的结果。
wan1330 发表于 2022-10-16 14:45
[Asm] 纯文本查看 复制代码
// 最大值
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)

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
cqwcns + 1 + 1 谢谢@Thanks!

查看全部评分

 楼主| cqwcns 发表于 2022-10-16 21:58
自己研究了一下,好像这个比较符合自己的需求。

[JavaScript] 纯文本查看 复制代码
        // 最大值
        const maxValue = (arr) => {
            // 首先根据数组的第一个对象,生成一个空的对象
            let obj = { ...arr[0] };
            Object.keys(arr[0]).forEach((key, index) => {
                obj[key] = index ? '' : '最大值'
            });

            // 通过累加器返回最大值
            return arr.reduce((pre, cur) => {
                for (const key in pre) {
                    pre[key] = pre[key] && typeof pre[key] === "number" ? Math.max(pre[key], cur[key]) : pre[key] ? pre[key] : cur[key]
                }
                return pre
            }, obj)
        }

        console.log('maxValue', maxValue(arrData))
        // {col0: '最大值', col1: 0.86, col2: 0.92, col3: 0.68}
 楼主| cqwcns 发表于 2022-10-16 22:19
稍微修改了以下,支持数组对象直接添加最大值、最小值的行。

[JavaScript] 纯文本查看 复制代码
 // 原数据
        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[0] };
            Object.keys(arr[0]).forEach((key, index) => {
                obj[key] = index ? '' : isMax?'最大值':'最小值'
            });

            // 通过累加器计算
            const res = arr.reduce((pre, cur) => {
                for (const key in pre) {
                    pre[key] = pre[key] && typeof pre[key] === "number" ? isMax?Math.max(pre[key], cur[key]):Math.min(pre[key], cur[key]) : pre[key] ? pre[key] : cur[key]
                }
                return pre
            }, obj)

            // 添加到原数组
            arr.push(res)

        }

        // 添加最大值行
        pushMaxOrMin(arrData,1)
        // 添加最小值行
        pushMaxOrMin(arrData,0)
        console.table(arrData)
Dropless 发表于 2022-10-17 01:00
我觉得从最大值, 最小值等等方法剥离出来一个抽象的逻辑要好一点, 你这个一堆三元运算符挤在一起看着不头疼吗? 我反正是看都不愿看.

既然是对列作运算, 我的思路是先写一个列选择器, 返回指定列的数据, 这样不仅是求最大值, 求最小值, 以后要是有新的计算, 比如求平均值等等, 这个都可以复用.
[JavaScript] 纯文本查看 复制代码
// 原数据
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[colKey]) return memo[colKey];
    let col = [];
    data.forEach( element => {
        col.push(element[colKey]);
    })
    memo[colKey] = col;
    return col;
}

// 获得对象的key
const colKeys = Object.keys(arrData[0]);

let maxRow = {}, minRow = {};
colKeys.forEach( (colKey, index) => {
    if (!index) {
        maxRow[colKey] = "最大值";
        minRow[colKey] = "最小值";
    }
    else {
        maxRow[colKey] = Math.max(...selectCol(arrData, colKey));
        minRow[colKey] = Math.min(...selectCol(arrData, colKey));
    }
})

console.table([...arrData, maxRow, minRow]);


免费评分

参与人数 1吾爱币 +2 热心值 +1 收起 理由
cqwcns + 2 + 1 谢谢@Thanks!

查看全部评分

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 05:51

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表