2010-07-06 22 views
0

我有任何結構數組。陣列中的每個結構具有以下屬性:合併具有相同用戶標識的結構,然後根據屬性進行排序

  1. USER_ID
  2. num_hot_dogs_eaten
  3. date_last_pigged_out

這就是我想做的事:

  1. 查找具有匹配的結構user_id's,並將它們合併到一個結構記錄中,其中num_hot_dogs_eaten是所有匹配項的總和記錄和date_last_pigged_out是用戶清空的最近日期。

  2. 將結構數組按num_hot_dogs_eaten(優先級的第一級)和date_last_pigged_out(優先級的第二級...最近的第一個)排序。

  3. 返回一個新的結構化排序數組。

回答

1

使用此:

def f(users) 
    r = [] 
    users.each do |u| 
    new_match = false 
    match = r.find {|x| x.user_id == u.user_id } 
    unless match 
     match = u.dup 
     r << match 
     new_match = true 
    end 
    match.num_hot_dogs_eaten += u.num_hot_dogs_eaten unless new_match 
    match.date_last_pigged_out = 
     [match, u].max_by(&:date_last_pigged_out).date_last_pigged_out 
    end 
    r.sort_by {|u| [u.num_hot_dogs_eaten, u.date_last_pigged_out] }. 
    reverse 
end 
0

功能更強大的編程方法:

User = Struct.new(:user_id, :num_hot_dogs_eaten, :date_last_pigged_out) 
ONE_DAY = 60 * 60 * 24 

class Object 
    def returning(object) 
    yield object 
    object 
    end 
end 

users = [ 
    User.new(1, 3, Time.now), 
    User.new(1, 2, Time.now + ONE_DAY), 
    User.new(1, 1, Time.now - ONE_DAY), 
    User.new(2, 2, Time.now - ONE_DAY), 
    User.new(2, 3, Time.now), 
    User.new(3, 5, Time.now - ONE_DAY), 
] 

users.inject(Hash.new { |hash, key| hash[key] = Hash.new { |hash, key| hash[key] = [] } }) do |collection, user| 
    returning(collection) do 
    collection[user.user_id][:num_hot_dogs_eaten] << user.num_hot_dogs_eaten 
    collection[user.user_id][:date_last_pigged_out] << user.date_last_pigged_out 
    end 
end.map do |user_id, stats| 
    User.new(user_id, stats[:num_hot_dogs_eaten].inject(&:+), stats[:date_last_pigged_out].max) 
end.sort_by { |user| [user.num_hot_dogs_eaten, user.date_last_pigged_out] }.reverse 

實際實施(假設你有returning定義):

users.inject(Hash.new { |hash, key| hash[key] = Hash.new { |hash, key| hash[key] = [] } }) do |collection, user| 
    returning(collection) do 
    collection[user.user_id][:num_hot_dogs_eaten] << user.num_hot_dogs_eaten 
    collection[user.user_id][:date_last_pigged_out] << user.date_last_pigged_out 
    end 
end.map do |user_id, stats| 
    User.new(user_id, stats[:num_hot_dogs_eaten].inject(&:+), stats[:date_last_pigged_out].max) 
end.sort_by { |user| [user.num_hot_dogs_eaten, user.date_last_pigged_out] }.reverse 
相關問題