Ruby按嵌套哈希指定键值排序二维数组并保留原键元素
Ruby 二维术语数组按多语言子字段排序方案
问题核心
需要对存储多语言术语的二维数组重排序,原数组默认按英文名称排序,结构如下:
english_sorted_terms = [ [ "A1_english", {"domains"=>[], "en"=>{"name"=>"A_english", "def"=>"A"}, "de"=>{"name"=>"Z_german", "def"=>"..." }} ], [ "Z1_english", {"domains"=>[], "en"=>{"name"=>"Z_english", "def"=>"Z"}, "de"=>{"name"=>"A_german", "def"=>"..."}} ] ]
排序要求:按每个条目下德语(de)分支的name字段升序排列,最终"Z1_english"条目因为对应德语名是"A_german",需要排在数组第一位。
原有代码错误原因
之前尝试的写法都没找对排序的操作对象:
- 第一段写法先通过
map提取了每个子数组里的哈希部分,直接丢弃了子数组首位的英文键,排序后自然丢失原结构 - 第二段写法是在
map循环里对单个条目做内部排序,根本没有调整外层数组的元素顺序,逻辑完全错位 - 单独调用
sort_by! { |key| key["de"]['name'] }会丢失首元素的原因也一样:传入排序的集合本身就没包含子数组的首键字段,数据源不全结果必然不对
正确实现
不需要拆分、重组子数组结构,直接对外层数组调用sort_by,在块内提取每个条目的排序依据字段即可,完全保留每个子数组的原始结构:
# 非原地排序,返回排序后的新数组 german_sorted_terms = english_sorted_terms.sort_by { |term| term[1].dig("de", "name") } # 如果需要直接修改原数组,用带感叹号的原地排序版本即可 # english_sorted_terms.sort_by! { |term| term[1].dig("de", "name") }
这里用
Hash#dig是容错写法,就算某条数据缺失de节点或者name字段也不会抛出空指针报错,比连续写方括号取值更健壮;如果能保证所有条目字段完整,写term[1]["de"]["name"]效果完全一致。
结果验证
执行上述代码后,数组首条目为:
[ "Z1_english", {"domains"=>[], "en"=>{"name"=>"Z_english", "def"=>"Z"}, "de"=>{"name"=>"A_german", "def"=>"..."}} ]
完全符合预期排序要求,所有条目的内部结构没有任何改动。
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

