如何在Rust中按JSON内的章节数值排序数组?
如何按JSON中的浮点章节值对数组排序?
需求是对包含章节字段的JSON数组按数值排序,示例输入:
[{"chapter": "3"},{"chapter": "1.5"},{"chapter": "2"},{"chapter": "1"}]
期望排序结果:
[{"chapter": "1"},{"chapter": "1.5"},{"chapter": "2"},{"chapter": "3"}]
实际处理时发现章节字段嵌套在attributes中,真实数据格式为:
[{"attributes":{"chapter":"3"}},{"attributes":{"chapter":"2"}}]
尝试过的无效方案
- 使用
sort_unstable_by_key结合as_i64转换:章节值是浮点字符串,转整数会失败,无法完成排序 - 改用
as_f64转换:serde_json的Value类型如果是字符串,as_f64会返回None,无法获取数值进行比较 - 截取章节字符串的整数部分转为i32:只能实现整数级排序,无法区分"1"和"1.5"这类带小数的章节
最终可行方案
使用sort_unstable_by自定义排序逻辑,将章节字符串解析为f32后用total_cmp做数值比较,代码示例:
use serde_json::Value; fn sort_chapters(data: &mut [Value]) { data.sort_unstable_by(|a, b| { // 安全获取嵌套的chapter字段并转为f32 let parse_chapter = |val: &Value| { val.get("attributes") .and_then(|attr| attr.get("chapter")) .and_then(|ch| ch.as_str()) .unwrap_or("0") .parse::<f32>() .unwrap_or(0.0) }; let chapter_a = parse_chapter(a); let chapter_b = parse_chapter(b); chapter_a.total_cmp(&chapter_b) }); }
说明
- 通过
get方法逐层访问attributes.chapter字段,避免嵌套结构不存在导致的 panic - 将章节字符串解析为f32,确保能正确识别带小数的章节值
- 使用
total_cmp处理浮点数比较,覆盖包括NaN在内的所有浮点数情况(如果数据里不会出现NaN,也可以用普通比较运算符) sort_unstable_by相比稳定排序性能更高,适合不需要保留相等元素原始顺序的场景
内容的提问来源于stack exchange,提问作者Hovercraft
相关产品推荐
相关产品推荐

