Ruby中按distance字段对哈希数组Map排序失败的解决方法
排序失败核心原因
你写的几种排序方式不生效,是三个明确的代码错误导致的:
itemmap是Hash构成的数组,不是挂载了distance实例方法的自定义对象,直接写item.distance会触发NoMethodError,根本拿不到值- 对数组调用
sort_by { |k, v| v[:distance] }属于参数误用:数组遍历时单块参数就是单个Hash元素,不会自动拆成键值对k、v,这种写法永远拿不到:distance对应的值 - 你存储的
distance是字符串格式,哪怕取值正确,直接按字符串排序会遵循字典序规则,遇到跨位数的数值(比如"1000.0"和"999.0")会排错顺序。
正确实现代码
首先修正排序逻辑,兼容你当前生成的itemmap结构(注意你贴的itemmap生成代码末尾缺一个右括号,运行时本身就会报语法错):
# 按distance数值升序排序,兼容字符串/符号两种键格式,自动转浮点数避免字符串排序错误 sorted_items = itemmap.sort_by { |item| item['distance'].to_f }
如果想从数据生成阶段就规避键类型、值类型问题,可以优化itemmap的生成逻辑:
# 补全原代码缺失的闭合括号,统一Hash键为符号类型,distance直接存数值 itemmap = items.map do |item| calc_distance = get_item_distance(item, [params[:latitude], params[:longitude]]).try(:round, 1) item.attributes.symbolize_keys.merge(distance: calc_distance) end # 后续排序可以直接取符号键,逻辑更简洁 sorted_items = itemmap.sort_by { |item| item[:distance] }
注:你贴的待排序样例里第三个元素id字段缺值,属于手写笔误,补全对应值即可,不影响排序逻辑运行。
内容的提问来源于stack exchange,提问作者Amer Bearat
相关产品推荐
相关产品推荐

