2014-01-18 14 views
0

所以我得到記錄的數組願意做這樣的事情:如何排序優先從ActiveRecord的,我的具體屬性

VIP_LIST = ['John', 'Larry', 'Dan'] 

records = [ 
{ name: "Adam" }, 
{ name: "Larry" }, 
{ name: "John" }, 
{ name: "Eric" }, 
{ name: "Dan" } 
] 

# This is what I want to end up with: 

sort_please(records, VIP_LIST) 
    => [ 
    { name: "John" }, 
    { name: "Larry" }, 
    { name: "Dan" }, 
    { name: "Adam" }, 
    { name: "Eric" } 
    ] 

我怎樣才能做到這一點?

P.S.有可能是在VIP_LIST甚至不是在記錄

+0

所以基本上把對應的列表項第一的記錄,在列表中的順序,然後按原來的順序休息? – Noctua

+0

@Noctua究竟:) – Ryan

+0

使用排序與塊。 –

回答

1

試試這個:

records.sort_by do |x| 
    [VIP_LIST.index(x[:name]) || VIP_LIST.length, records.index(x)] 
end 

# => [{:name=>"John"}, {:name=>"Larry"}, {:name=>"Dan"}, {:name=>"Adam"}, {:name=>"Eric"}] 
+2

這與我的答案基本相同,但轉換爲一行,並且缺少保持非VIP按相同順序的位。我認爲這是要求的一部分,除非我錯了。它以相反的順序返回Eric和Adam。 – Kal

+0

是的。 eric和adam正好相反 – rejin

+0

我沒有注意到我在最後的順序錯誤,現在應該沒問題。 – xlembouras

3

這不是一個聰明的一個襯墊值,但它的工作原理:

VIP_LIST = ['John', 'Larry', 'Dan', 'Fred'] 

records = [ 
{ name: "Adam" }, 
{ name: "Larry" }, 
{ name: "John" }, 
{ name: "Eric" }, 
{ name: "Dan" } 
] 

    sorted = records.sort_by do |record| 
    name = record[:name] 
    if VIP_LIST.include?(name) 
     VIP_LIST.index(name) 
    else 
     records.index(record) + VIP_LIST.length 
    end 
    end 

    p sorted # => [{:name=>"John"}, {:name=>"Larry"}, {:name=>"Dan"}, {:name=>"Adam"}, {:name=>"Eric"}] 
1

這一個?

new_arr = [] 
VIP_LIST.each do |v| 
    new_arr << records.select {|r| r[:name] == v } unless nil? 
end 
new_arr.flatten! 
new_arr = new_arr + (records - new_arr) 
0

我認爲這是既清晰又簡潔:

vip = records.select{ |hash| VIP_LIST.include? hash[:name] } 
vip = vip.sort_by{|x| VIP_LIST.find_index(x[:name])} #reorder vip array 
sorted_records = (vip + records).uniq 
+0

不錯,但是它在約翰之前回歸拉里。我認爲他們應該是列出的順序,除非我錯了。 – Kal

+0

啊,是的,我錯過了關於維護訂單的要求。謝謝。 – benjaminjosephw