在Ruby中对对象的哈希表(通过对象的属性)进行排序

时间:2012-02-01 22:23:32

标签: ruby sorting object hash attributes

假设我有一个名为Person的类,它包含姓氏,名字,地址等内容。

我还有一个Person对象的哈希表,需要按姓氏和名字排序。 我知道sort_by不会永久改变哈希,这很好,我只需要按顺序打印。目前,我正在尝试使用以下方式进行排序/打印:

@hash.sort_by {|a,b| a <=> b}.each { |person| puts person.last}

我重载了&lt; =&gt;运算符按last / first排序,但似乎没有任何实际排序。那里的放置只是以散列的原始顺序输出。我花了4天的时间试图解决这个问题(这是一个学校作业,也是我的第一个Ruby程序)。有任何想法吗?我确信这很容易,但我正在努力让我的大脑摆脱C ++的思维方式。

3 个答案:

答案 0 :(得分:4)

您似乎对sortsort_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}

这也称为schwartzian transform

在您的情况下,集合是一个哈希,所以事情稍微复杂一些:传递给块的值是包含键/值对的数组,因此您需要从该对中提取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的出色解释。