2012-08-03 95 views
1

我想基於給定的鍵值對散列數組進行排序,並將首先在數組頂部返回該值,然後在其餘數據之前。如何按值排序哈希數組?

實施例將是:

students = [{name: "John Doe", age: 16, adviser: "Mrs. Robinson"}, 
      {name: "John Smith", age: 18, adviser: "Mrs. Williams"}, 
      {name: "Michael Rodriguez", age: 17, adviser: "Mr. Lee"}] 

def sort_by_adviser(data, name) 
    ... 
end 

> sort_by_adviser(students, "Mr. Lee") 
=> [{name: "Michael Rodriguez", age: 17, adviser: "Mr. Lee"}, 
    {name: "John Doe", age: 16, adviser: "Mrs. Robinson"}, 
    {name: "John Smith", age: 18, adviser: "Mrs. Williams"}] 

> sort_by_adviser(students, "Mrs. Williams") 
=> [{name: "John Smith", age: 18, adviser: "Mrs. Williams"}, 
    {name: "Michael Rodriguez", age: 17, adviser: "Mr. Lee"}, 
    {name: "John Doe", age: 16, adviser: "Mrs. Robinson"}] 

這裏的輸出所帶來的顧問的在列表的頂部名稱,然後由陣列中的其他散列之前。

> sort_by_keyvalue(data, "Z") 
=> [{letter: 'Z'}, 
    {letter: 'A'}, 
     . 
     . 
     . 
    {letter: 'Y'}] 

> sort_by_keyvalue(data, 5) 
=> [{number: 5, value: 'value1'}, 
    {number: 5, value: 'value2'}, 
    {number: 5, value: 'value3'}, 
    {number: 9, value: 'value1'}, 
    {number: 9, value: 'value2'}, 
    {number: 8, value: 'value1'}, 
    {number: 8, value: 'value2'}, 
    {number: 7, value: 'value1'}, 
    {number: 6, value: 'value1'}, 
    {number: 4, value: 'value1'}, 
    {number: 3, value: 'value1'}, 
    {number: 2, value: 'value1'}, 
    {number: 1, value: 'value1'}, 
    {number: 1, value: 'value2'}, 
    {number: 0, value: 'value1'}] 

任何人都知道該怎麼辦呢?

+0

做你想做任何排序,或者只是移動匹配一個擺在首位? – davidrac 2012-08-03 19:39:21

+0

先移動匹配,然後做一個sort_by {| k,v | k [:key]}對數組中剩餘的散列進行排序。 – rubies 2012-08-03 19:48:48

回答

1

你可以這樣做:

def sort_by_adviser(data, name) 
    data = data.sort{|x,y|x[:adviser] <=> y[:adviser]} 
    i = data.index{|h|h[:adviser] = name} 
    h = data.delete_at i 
    data.unshift h 
end 
2
def creamy_sort(key, value, arr) 
    top, bottom = arr.partition{|e| e[key] == value } 
    top.concat(bottom.sort{|a,b| b[key] <=> a[key]}) 
end 

creamy_sort(:adviser, "Mr. Lee", students) 
1

我有這樣的解決方案:

students = [{name: "John Doe", age: 16, adviser: "Mrs. Robinson"}, 
      {name: "John Smith", age: 18, adviser: "Mrs. Williams"}, 
      {name: "Michael Rodriguez", age: 17, adviser: "Mr. Lee"}] 

def sort_by_adviser(data, *name) 
    data.sort_by{| entry |  
    [ 
     name.index(entry[:adviser]) || 999, 
     entry[:age], entry[:name] #2nd sort criteria 
    ] 
    } 
end 

p sort_by_adviser(students, "Mr. Lee") 
#[{:name=>"Michael Rodriguez", :age=>17, :adviser=>"Mr. Lee"}, {:name=>"John Doe", :age=>16, :adviser=>"Mrs. Robinson"}, {:name=>"John Smith", :age=>18, :adviser=>"Mrs. Williams"}] 

p sort_by_adviser(students, "Mrs. Williams") 
# [{:name=>"John Smith", :age=>18, :adviser=>"Mrs. Williams"}, {:name=>"John Doe", :age=>16, :adviser=>"Mrs. Robinson"}, {:name=>"Michael Rodriguez", :age=>17, :adviser=>"Mr. Lee"}] 

我不明白,什麼是剩餘條目的排序。

你寫道:然後在其餘的數據前面。散列的順序標準是什麼?

我選擇了年齡,然後是名字。但是你可以根據你的需要進行調整。

1
def weird_sort(array, key, value) 
    return array.sort_by{|d| 2 <=> (d[key] == value).object_id} 
end 

這是基於true.object_id紅寶石等於2的事實。 一種奇怪的解決方案,這就是爲什麼它是一個weird_sort:p它也混淆了其他價值秩序...所以它只能保證你的值是相等的!

3

另一個FPGA實現:)

def sort_by_adviser(data, name) 
    data.each_with_index do |hash,index| 
     if hash[:adviser]==name 
     data.delete_at index #delete from array 
     data.unshift hash 
     break 
     end 
    end 
    data 
end 

> sort_by_adviser(students, "Mr. Lee") 
#=> [{:name=>"Michael Rodriguez", :age=>17, :adviser=>"Mr. Lee"}, {:name=>"John Doe", :age=>16, :adviser=>"Mrs. Robinson"}, {:name=>"John Smith", :age=>18, :adviser=>"Mrs. Williams"}]