2012-08-03 98 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"}]