假设我有一个名为Person的类,它包含姓氏,名字,地址等内容。
我还有一个Person对象的哈希表,需要按姓氏和名字排序。 我知道sort_by不会永久改变哈希,这很好,我只需要按顺序打印。目前,我正在尝试使用以下方式进行排序/打印:
@hash.sort_by {|a,b| a <=> b}.each { |person| puts person.last}
我重载了&lt; =&gt;运算符按last / first排序,但似乎没有任何实际排序。那里的放置只是以散列的原始顺序输出。我花了4天的时间试图解决这个问题(这是一个学校作业,也是我的第一个Ruby程序)。有任何想法吗?我确信这很容易,但我正在努力让我的大脑摆脱C ++的思维方式。
答案 0 :(得分:4)
您似乎对sort
和sort_by
sort
会产生从集合到块的两个对象,并希望您返回一个&lt; =&gt;喜欢值:-1,0或1取决于参数是否相等,升序或降序,例如
%w(one two three four five).sort {|a,b| a.length <=> b.length}
按长度对字符串进行排序。如果您要使用&lt; =&gt;这是要使用的表单。操作
sort_by
一次从集合中生成一个对象,并期望您返回要排序的内容 - 您不应该在此处进行任何比较。然后Ruby使用&lt; =&gt;在这些目标上对您的收藏进行排序。前面的例子可以改写为
%w(one two three four five).sort_by {|s| s.length}
在您的情况下,集合是一个哈希,所以事情稍微复杂一些:传递给块的值是包含键/值对的数组,因此您需要从该对中提取person对象。您也可以使用@hash.keys或@hash.values(取决于person对象是键还是值)
答案 1 :(得分:3)
如果你已经覆盖了&lt; =&gt;运算符适当地对Person对象进行排序,然后您可以执行以下操作:
@hash.sort_by{ |key, person| person }
因为sort_by将同时产生散列键和对象(在你的情况下是一个人)到块的每次迭代。因此,上面的代码将根据Person对象对您的哈希进行排序 - 您已经为其指定了&lt; =&gt;操作
答案 2 :(得分:0)
当您使用哈希#.sort_by
时,传递给块的参数是'key','value',而不是'element a'和'element b'。尝试:
@hash.sort_by{|key,value| value.last}.each{|key,value| puts value.last}
另外,请参阅Frederick Cheung对#sort
vs #sort_by
的出色解释。