吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 634|回复: 4
收起左侧

[讨论] JS指标值数组转排名数组的实现

[复制链接]
cqwcns 发表于 2023-2-15 17:19
首先我们有一个各省份的多项指标值,5列,即一共是5个指标。
需求是根据这个格式,计算各省对应指标的排名。


以下代码功能已实现,分享一下。


各位大佬如果有优化建议或更优雅的写法,欢迎拍砖,谢谢

[JavaScript] 纯文本查看 复制代码
                let obj = {
                    arrValue: [
                        ['广东省', '0.400143678', '0.921666149', '0.9197356', '0.04875', '0.04047619'],
                        ['北京市', '0.429216867', '0.968006563', '0.873073436', '0.04465383', '0.03539823'],
                        ['上海市', '0.375123396', '0.933398153', '0.894736842', '0.036930179', '0.037974684'],
                        ['四川省', '0.457677165', '0.96251802', '0.943161634', '0.024539877', '0.030120482'],
                        ['台湾省', '0.421784473', '0.943089431', '0.906382979', '0.03414264', '0.022900763']
                    ],
                    arrRank: [
                        ['广东省'],
                        ['北京市'],
                        ['上海市'],
                        ['四川省'],
                        ['台湾省']
                    ]
                };

                // 遍历arrValue第一个元素
                for (let i = 0; i < obj.arrValue[0].length; i++) {
                    // 忽略第一列
                    if (i) {
                        // 排序(为了避免改变原数组,加了...解构)
                        let arrSort = [...obj.arrValue].sort((a, b) => a[i] - b[i]);
                        // 提取一列城市名称为数组,得到排序好的城市名称
                        arrSort = arrSort.map(item => item[0]);

                        // 遍历arrRank
                        obj.arrRank.forEach(element => {
                            // 添加排名
                            element.push(arrSort.indexOf(element[0]) + 1)
                        });

                    }

                };

                console.log('obj.arrRank', obj.arrRank);
                // [
                //     ["广东省", 2, 1, 4, 5, 5],
                //     ["北京市", 4, 5, 1, 4, 3],
                //     ["上海市", 1, 2, 2, 3, 4],
                //     ["四川省", 5, 4, 5, 1, 2],
                //     ["台湾省", 3, 3, 3, 2, 1]
                // ]

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

pjy612 发表于 2023-2-16 11:04
也没多优雅的 核心逻辑好像就那样了。。。

ps.偷懒用了 lodash....
[JavaScript] 纯文本查看 复制代码
let arrRank = [...obj.arrValue];
for (let i = 0; i < arrRank[0].length; i++) {
    // 忽略第一列
    if (i) {
        let rankDict = Object.fromEntries(_.orderBy(arrRank,row=>row[i]).map((row,rank)=>([row[0],rank+1])));
        arrRank.forEach((row)=>{
            row[i]=rankDict[row[0]];
        });
    }
};
console.log(arrRank);

免费评分

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

查看全部评分

fortytwo 发表于 2023-2-17 12:30
[JavaScript] 纯文本查看 复制代码
obj = {
    arrValue: [
        ['广东省', '0.400143678', '0.921666149', '0.9197356', '0.04875', '0.04047619'],
        ['北京市', '0.429216867', '0.968006563', '0.873073436', '0.04465383', '0.03539823'],
        ['上海市', '0.375123396', '0.933398153', '0.894736842', '0.036930179', '0.037974684'],
        ['四川省', '0.457677165', '0.96251802', '0.943161634', '0.024539877', '0.030120482'],
        ['台湾省', '0.421784473', '0.943089431', '0.906382979', '0.03414264', '0.022900763']
    ],
    arrRank: [
        ['广东省'],
        ['北京市'],
        ['上海市'],
        ['四川省'],
        ['台湾省']
    ]
}


const values = obj.arrValue;
const ranks = obj.arrRank;
const n = values.length;
const m = values[0].length - 1;
const rankIndex = new Array(n);

// 初始化rankIndex
for (let i = 0; i < n; i++) {
  rankIndex[i] = i;
}

// 按照各项指标对省份数组进行排序
for (let j = m; j >= 1; j--) {
  rankIndex.sort((a, b) => values[b][j] - values[a][j]);
  let rank = 1;
  let currentValue = values[rankIndex[0]][j];
  for (let i = 0; i < n; i++) {
    const index = rankIndex[i];
    if (values[index][j] !== currentValue) {
      rank = i + 1;
      currentValue = values[index][j];
    }
    for (let k = 0; k < m + 1; k++) {
      values[index][k] = [values[index][k]];
    }
    values[index][j] = rank;
  }
}

// 将数组中每个元素转换为数字
for (let i = 0; i < n; i++) {
  for (let j = 1; j < m + 1; j++) {
    values[i][j] = Number(values[i][j][0]);
  }
}

// 构造结果数组
const result = new Array(n);
for (let i = 0; i < n; i++) {
  const row = new Array(m + 1);
  for (let j = 0; j < m + 1; j++) {
    row[j] = values[i][j];
  }
  result[i] = row;
}

console.log(result);
liangyun 发表于 2023-2-21 10:39
本帖最后由 liangyun 于 2023-2-21 10:49 编辑

> 为了避免改变原数组,加了...解构
这个还是会改变原数组的, 因为你这是浅拷贝

我写了一行比较长的代码, 简单测试了一下值没问题, 目测性能一般, 但是短

obj.arrRank = obj.arrValue.map(([name, ...scores]) =>
    [name, ...scores.map((score, idx) => obj.arrValue.map(it => it[idx + 1]).filter(it => it < score).length + 1)])

免费评分

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

查看全部评分

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

本版积分规则

返回列表

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

GMT+8, 2024-11-25 02:41

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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