2014年10月22日 星期三

[ 文章收集 ] How to Sort a Hash in Ruby

Source From Here 
Preface 
Let's say you have the following hash of people to ages: 
>> people = {:john=>23, :ken=>18, :peter=>54}
=> {:john=>23, :ken=>18, :peter=>54}

Now, what if we want to "sort" the hash into age order? We can't. At least, not exactly. Hashes are not meant to be in a certain order (though they are in Ruby 1.9) as they're a data structure where one thing merely relates to another thing. The relationships themselves are not elements of data in themselves. 

We can, however, build other data structures that represent sorted versions of the data within a hash. An Array, for example: 
# Let's say we want to get a list of the ages in order:
>> people.values.sort
=> [18, 23, 54]

This gives us the values but you might want to have both the values and their associated keys in a particular order. 

Enumerable To The Rescue! 
Luckily, Hash has the Enumerable module mixed in which provides us with methods like sort and sort_by. Let's give them a go: 
>> people[:alice]=31
=> 31
>> people
=> {:john=>23, :ken=>18, :peter=>54, :alice=>31}
>> people.sort # default will sorting with key of hash map
=> [[:alice, 31], [:john, 23], [:ken, 18], [:peter, 54]]

Next, let's use sort_by to get where we want to go (sorting by age): 
>> people.sort_by{|name, age| age}
=> [[:ken, 18], [:john, 23], [:alice, 31], [:peter, 54]]
>> people.sort_by{|name, age| age}.reverse # sorting by age in descending way
=> [[:peter, 54], [:alice, 31], [:john, 23], [:ken, 18]]

In this situation we're using sort_by to sort by a specific collection - the values (ages, in our case). Since integers (FixNum objects, in this case) can be compared with <=>, we're good to go. We get a nested array back with one element per hash element in order to preserve the 'ordering'. You can then use Array or other Enumerable methods to work with the result (tip: each* is a good place to start!

A More Complex Situation 
Let's make our hash more complex: 
>> people = {:fred=>{:name=>"Fred", :age=>23}, :joan=>{:name=>"Joan", :age=>18}, :pete=>{:name=>"Pete", :age=>54}}
=> {:fred=>{:name=>"Fred", :age=>23}, :joan=>{:name=>"Joan", :age=>18}, :pete=>{:name=>"Pete", :age=>54}}

This time we not only have a hash - we have a hash filled with other hashes. What if we want to sort by values within the nested hashes? It's much the same as before, except we address the inner hash during the sort: 
>> people.sort_by{|k, v| v[:age]}
=> [[:joan, {:name=>"Joan", :age=>18}], [:fred, {:name=>"Fred", :age=>23}], [:pete, {:name=>"Pete", :age=>54}]]

Supplement 
Basic : 內建型態與操作 - 雜湊型態 
Basic : 內建型態與操作 - 陣列型態

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...