ruby-on-rails - 试图理解 sort_by 函数在 Ruby 中的工作原理

标签 ruby-on-rails ruby arrays sorting

我正在学习教程 Bastards Book of Ruby我无法理解函数 sort_by 的工作原理。这是练习:

练习:按姓氏对姓名排序

给定一个以“FIRSTNAME LASTNAME”形式表示名称的字符串数组,使用 sort_by 和 split 返回按姓氏排序的数组。为简单起见,假设每个名字仅由两个用空格分隔的词组成(即只有“John Doe”而不是“Mary Jo Doe”)。

names = ["John Smith", "Dan Boone", "Jennifer Jane", "Charles Lindy", "Jennifer Eight", "Rob Roy"]

这是解决方案:

names = ["John Smith", "Dan Boone", "Jennifer Jane", "Charles Lindy", "Jennifer Eight", "Rob Roy"]
sorted_names = names.sort_by do |name|
   name.split(" ").reverse.join.upcase
end

puts sorted_names.join('; ')
# output=> Dan Boone; Jennifer Eight; Jennifer Jane; Charles Lindy; Rob Roy; John Smith

但是,当我运行代码时

sorted_names = names.sort_by do |name|
  puts name.split(" ").reverse.join.upcase
end

我得到输出:

SMITHJOHN
BOONEDAN
JANEJENNIFER
LINDYCHARLES
EIGHTJENNIFER
ROYROB

这与 puts sorted_names.join('; ')

的输出完全不同

我认为该方法实际上是在操作数据(因此 name.split("").reverse.join.upcase)然后将其保存到新数组 sorted_names。但显然不是。所以,我的问题是有人可以解释为什么这个 sort_by 方法是这样的。我是 Ruby 的新手,我尝试查看 Ruby docs寻求解释,但找不到。我觉得我不理解 Ruby 中的一个重要概念,如果有任何帮助或见解,我将不胜感激。

最佳答案

sort_by 有点像这样做:

a.map {|item| [f(item), item]}.sort.map {|key, item| item}

也就是说,sort_by block 用于为数组中的每个值计算一个排序键,然后对这些键进行排序,然后将这些键映射回原始值。

所以你看到的是那些键,在它们被用来排序之前。除了 ranksrejoined 指出的,puts 返回 nil,所以通过检查你破坏了函数的键!

关于ruby-on-rails - 试图理解 sort_by 函数在 Ruby 中的工作原理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8966580/

相关文章:

jQuery 下拉菜单不适用于 Bootstrap 平板电脑或手机尺寸

ruby-on-rails - 为什么 ruby​​ REGEX\A...\z 允许在开始时输入任何内容?

ruby-on-rails - ruby 版本之间的时区解析差异

sql - Rails 每天显示不同的对象

ruby-on-rails - Controller Action 中未定义的方法新

ruby-on-rails - Rails : How to mock gems, 如 fb_graph

mysql - 使用 ActiveRecord 急切地从 User 表中加载单个条目以及关联的 own_to 记录

javascript - 如何从对象数组中提取多属性重复项?

c++ - 错误:The thread 0x4c0c has exited with code 0 (0x0). Exception thrown: read access violation. **this** was nullptr

使用日志函数(没有 math.h)和数组计算 C 中的字母表