按分数总和降序映射用户数组的技术问题求助
问题描述
给定如下JSON数据:
{"user": [{"username": "x1", "pfp": "", "scores": [{"easy": 10, "normal": 1, "hard": 2, "oni": 3, "uraoni": 4}]}, {"username": "x2", "pfp": "", "scores": [{"easy": 3, "normal": 1, "hard": 2, "oni": 3, "uraoni": 4}]}, {"username": "x3", "pfp": "", "scores": [{"easy": 5, "normal": 1, "hard": 2, "oni": 3, "uraoni": 4}]}, {"username": "x4", "pfp": "", "scores": [{"easy": 0, "normal": 40, "hard": 2, "oni": 3, "uraoni": 4}]}]}
期望按分数总和降序排列的用户名为:x4, x1, x2, x3(x4总分49,x1总分20,x2总分13,x3总分15)。
尝试用map结合reduce计算总分再排序,但执行reduce()时报错,使用的代码如下:
let userscopy = userjson userscopy.map((user) => ( user.scores[0] = JSON.parse(user.scores).reduce((a, b) => a + b) ))
错误提示:JSON.parse: unexpected character at line 1 column 2 of the JSON string
错误原因分析
- 多余的
JSON.parse调用:user.scores已经是解析完成的JS对象数组,不是JSON字符串,强行解析会直接报错。 reduce用法错误:直接对对象调用reduce无效,必须先把对象里的分数值提取成数组才能用reduce求和。map的误用:map的作用是生成新数组,不是直接修改原数组,且你最终需要的是排序结果,映射只是中间步骤。
解决方法
完整实现代码
// 假设userjson是已解析的JS对象 const userjson = {"user": [{"username": "x1", "pfp": "", "scores": [{"easy": 10, "normal": 1, "hard": 2, "oni": 3, "uraoni": 4}]}, {"username": "x2", "pfp": "", "scores": [{"easy": 3, "normal": 1, "hard": 2, "oni": 3, "uraoni": 4}]}, {"username": "x3", "pfp": "", "scores": [{"easy": 5, "normal": 1, "hard": 2, "oni": 3, "uraoni": 4}]}, {"username": "x4", "pfp": "", "scores": [{"easy": 0, "normal": 40, "hard": 2, "oni": 3, "uraoni": 4}]}]}; // 1. 复制数组避免修改原数据,同时为每个用户计算总分 const usersWithTotal = [...userjson.user].map(user => { // 提取分数对象的所有数值,再累加求和 const totalScore = Object.values(user.scores[0]).reduce((sum, score) => sum + score, 0); // 返回包含总分的新对象,不破坏原数据结构 return { ...user, totalScore }; }); // 2. 按总分降序排序 const sortedUsers = usersWithTotal.sort((a, b) => b.totalScore - a.totalScore); // 3. 提取排序后的用户名数组 const sortedUsernames = sortedUsers.map(user => user.username); console.log(sortedUsernames); // 输出: ["x4", "x1", "x2", "x3"]
关键代码说明
[...userjson.user]:浅复制原用户数组,避免修改原始数据。Object.values(user.scores[0]):把分数对象(比如{"easy":10,...})转换成数值数组([10,1,2,3,4]),让reduce可以正常累加。sort((a,b) => b.totalScore - a.totalScore):通过b-a实现降序排序,若要升序则改成a.totalScore - b.totalScore。
内容的提问来源于stack exchange,提问作者Cerrebe
相关产品推荐
相关产品推荐

