如何使用JavaScript/JQuery按分数、性别、姓名排序排名
问题求助:多数组排序与存储方案疑问
数据情况与需求说明
我有三个平行数组,数据量约25000条,想先确认这种存储方案是否适用:
var arrayScores = [10, 21, 2, 35, 19, 85, 96, 70, 85, 19, 100, 11, 35, 70, 98, 81, 92]; var arrayGenders = ['M', 'M', 'F', 'F', 'M', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F']; var arrayNames = ['John', 'Fred', 'Jacque', 'Andrea', 'Andrew', 'Jacob', 'Dylan', 'Diana', 'Rahel', 'Raphael', 'Bob', 'Mariam', 'Fatma', 'Ahmed', 'Barack', 'Joyce', 'Taina'];
需要按照以下规则排序生成排名:
- 分数降序
- 分数相同则性别升序(F在前,M在后)
- 性别也相同则姓名升序
预期输出结果:
1.Bob-100, 2.Barack-98, 3.Dylan-96, 4.Taina-92, 5.Rahel-85, 6.Jacob-85, 7.Joyce-81, 8.Diana-70, 9.Ahmed-70, 10.Andrea-35, 11.Fatma-35, 12.Fred-21, 13.Andrew-19, 14.Raphael-19, 15.Mariam-11, 16.John-10, 17.Jacque-2
当前代码问题
我写了下面的代码,但无法得到预期结果,作为JavaScript初学者,请求帮忙修正:
var arrayScores = [10, 21, 2, 35, 19, 85, 96, 70, 85, 19, 100, 11, 35, 70, 98, 81, 92]; var arrayGenders = ['M', 'M', 'F', 'F', 'M', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F']; var arrayNames = ['John', 'Fred', 'Jacque', 'Andrea', 'Andrew', 'Jacob', 'Dylan', 'Diana', 'Rahel', 'Raphael', 'Bob', 'Mariam', 'Fatma', 'Ahmed', 'Barack', 'Joyce', 'Taina']; var rank = 1; arrayScores.forEach((score, index) => { const gender = arrayGenders[index], name = arrayNames[index]; console.log("Name: "+name+" Gender: "+gender+ " Score: "+score+ " Rank: "+rank); rank++; });
解决方案
1. 存储方案评估
你当前用三个平行数组存储数据的方式,虽然能运行,但维护性极差——一旦某个数组的索引出现错位,整个数据就会混乱。对于25000条数据来说,推荐把数据合并成对象数组,每个对象包含单个用户的完整信息,这样可读性、可维护性都会大幅提升,而且JS完全能轻松处理25000条对象数据,内存和性能都不会有问题。
2. 排序与排名实现
下面是修正后的代码,包含数据合并、排序、生成预期格式的完整逻辑:
// 原始数据 var arrayScores = [10, 21, 2, 35, 19, 85, 96, 70, 85, 19, 100, 11, 35, 70, 98, 81, 92]; var arrayGenders = ['M', 'M', 'F', 'F', 'M', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F']; var arrayNames = ['John', 'Fred', 'Jacque', 'Andrea', 'Andrew', 'Jacob', 'Dylan', 'Diana', 'Rahel', 'Raphael', 'Bob', 'Mariam', 'Fatma', 'Ahmed', 'Barack', 'Joyce', 'Taina']; // 步骤1:合并为对象数组(每个对象对应一个用户的完整信息) const users = arrayScores.map((score, index) => ({ name: arrayNames[index], gender: arrayGenders[index], score: score })); // 步骤2:按照规则排序 users.sort((a, b) => { // 首先按分数降序 if (b.score !== a.score) { return b.score - a.score; } // 分数相同则按性别升序(F的字母顺序在M前,localeCompare返回负数时a排在b前) if (a.gender !== b.gender) { return a.gender.localeCompare(b.gender); } // 性别相同则按姓名升序 return a.name.localeCompare(b.name); }); // 步骤3:生成预期格式的排名字符串 const rankResult = users.map((user, index) => `${index + 1}.${user.name}-${user.score}`).join(', '); // 输出结果 console.log(rankResult);
代码说明
- 数据合并:用
map方法把三个平行数组转换成对象数组,确保每个用户的信息绑定在一起,避免索引错位问题。 - 排序逻辑:使用数组的
sort方法,依次按照分数、性别、姓名的优先级排序:- 分数降序:用
b.score - a.score,数值大的排在前面。 - 性别升序:用
localeCompare比较字符串,'F'会排在'M'前面。 - 姓名升序:同样用
localeCompare按字母顺序排序。
- 分数降序:用
- 生成排名:用
map给每个排序后的用户添加排名序号,再用join拼接成预期的字符串格式。
运行这段代码后,输出结果会完全符合你的预期。
内容的提问来源于stack exchange,提问作者Job Gondwe
相关产品推荐
相关产品推荐

