JS统计国家出现次数的数组调用sort()无效如何正确实现升序排序?
问题核心原因
你犯了JS基础类型误用的错误:arrResults虽然被声明为数组,但你写入的FR:40、US:1511这类内容根本不是数组元素,而是挂载在数组对象上的自定义字符串属性。
JS数组的sort()方法只会处理数字索引对应的元素,完全不会触碰这些自定义字符串属性,你打印arrResults.length会发现值一直是0——从数组的角度看它自始至终都是空数组,当然怎么调用sort都不会有任何变化。
你写的那种[FR: 40, US: 1511...]的结构本身就是非法的数组语法,实际运行时JS引擎只会把它识别为“带额外属性的空数组”,根本不存在可排序的元素集合。你之前测试sort能正常工作,是因为测试用的是存了正常索引元素的数组,和当前场景完全不是一回事。
修复方法
- 统计计数阶段不要用数组存结果,改用普通对象或者
Map做计数映射 - 需要排序时,先把计数映射转成由
[国家编码, 出现次数]二元组组成的真正数组,再传入比较函数按次数升序排序
修改后的可运行代码:
var geoip = require('geoip-lite') const fs = require('fs') let data = fs.readFileSync('./ip_new.txt') let iplocation = "" let arrLocations = [] // 计数用普通对象,不要用数组 const countResult = {} const arrIP = data.toString().split("\r\n") for(let item of arrIP){ iplocation = geoip.lookup(item) arrLocations.push(iplocation.country) } for(let code of arrLocations){ countResult[code] = (countResult[code] || 0) + 1 } // 转成可排序数组后按次数升序排 const sortedResult = Object.entries(countResult).sort((prev, curr) => prev[1] - curr[1]) console.log(sortedResult)
运行后输出的结构和你预期的一致,按出现次数从低到高排列:
[ ['ID', 1], ['HK', 1], ['LU', 3], ['BH', 19], ['NL', 19], ['ZA', 19], ...其余条目 ]
如果后续需要按国家编码取次数,直接遍历排序后的数组即可,也可以把排序后的结果传入new Map()生成有序的键值对结构,不要试图给数组加自定义属性来存这类统计数据。
内容的提问来源于stack exchange,提问作者Adam Campbell
相关产品推荐
相关产品推荐

