Вы можете реализовать алгоритм назначения, который вы описываете следующим образом.
def assign(nbr_teams, players)
flip = [true, false].cycle
players.
sort_by { |p| p[:rating] }.
each_slice(nbr_teams).
map { |a| flip.next ? a.reverse : a }.
transpose
end
assign(4, players)
#=> [[{:name=>"Osman", :rating=>6}, {:name=>"Mahsam", :rating=>7}],
# [{:name=>"Aj", :rating=>3}, {:name=>"Bilal", :rating=>8}],
# [{:name=>"Usama", :rating=>2}, {:name=>"Owen", :rating=>15}],
# [{:name=>"Qasim", :rating=>1}, {:name=>"Kaka", :rating=>20}]]
Назначения были бы следующими, если бы было 2 команды.
assign(2, players)
#=> [[{:name=>"Usama", :rating=>2}, {:name=>"Aj", :rating=>3},
# {:name=>"Bilal", :rating=>8}, {:name=>"Owen", :rating=>15}],
# [{:name=>"Qasim", :rating=>1}, {:name=>"Osman", :rating=>6},
# {:name=>"Mahsam", :rating=>7}, {:name=>"Kaka", :rating=>20}]]
Шаги следующие.
nbr_teams = 4
flip = [true, false].cycle
#=> #<Enumerator: [true, false]:cycle>
Массив # цикл работает так: flip.next #=> true
, flip.next #=> false
, flip.next #=> true
и т. Д. Продолжая,
a = players.sort_by { |p| p[:rating] }
#=> [{:name=>"Qasim", :rating=>1}, {:name=>"Usama", :rating=>2},
# {:name=>"Aj", :rating=>3}, {:name=>"Osman", :rating=>6},
# {:name=>"Mahsam", :rating=>7}, {:name=>"Bilal", :rating=>8},
# {:name=>"Owen", :rating=>15}, {:name=>"Kaka", :rating=>20}]
b = a.each_slice(nbr_teams)
#=> #<Enumerator:
# [{:name=>"Qasim", :rating=>1}, {:name=>"Usama", :rating=>2},
# {:name=>"Aj", :rating=>3}, {:name=>"Osman", :rating=>6},
# {:name=>"Mahsam", :rating=>7}, {:name=>"Bilal", :rating=>8},
# {:name=>"Owen", :rating=>15}, {:name=>"Kaka", :rating=>20}]
# :each_slice(4)>
Мы можем преобразовать этот перечислитель в массив, чтобы увидеть объекты, которые он будет генерировать, и передать map
.
b.to_a
#=> [[{:name=>"Qasim", :rating=>1}, {:name=>"Usama", :rating=>2},
# {:name=>"Aj", :rating=>3}, {:name=>"Osman", :rating=>6}],
# [{:name=>"Mahsam", :rating=>7}, {:name=>"Bilal", :rating=>8},
# {:name=>"Owen", :rating=>15}, {:name=>"Kaka", :rating=>20}]]
Постоянно
c = b.map { |a| flip.next ? a.reverse : a }
#=> [[{:name=>"Osman", :rating=>6}, {:name=>"Aj", :rating=>3},
# {:name=>"Usama", :rating=>2}, {:name=>"Qasim", :rating=>1}],
# [{:name=>"Mahsam", :rating=>7}, {:name=>"Bilal", :rating=>8},
# {:name=>"Owen", :rating=>15}, {:name=>"Kaka", :rating=>20}]]
c.transpose
#=> [[{:name=>"Osman", :rating=>6}, {:name=>"Mahsam", :rating=>7}],
# [{:name=>"Aj", :rating=>3}, {:name=>"Bilal", :rating=>8}],
# [{:name=>"Usama", :rating=>2}, {:name=>"Owen", :rating=>15}],
# [{:name=>"Qasim", :rating=>1}, {:name=>"Kaka", :rating=>20}]]
Может быть желательно преобразовать результаты в массив хэшей.
assign(4, players).map { |a| a.map { |h| [h[:name], h[:rating]] }.to_h }
#=> [{"Osman"=>6, "Mahsam"=>7},
# {"Aj" =>3, "Bilal" =>8},
# {"Usama"=>2, "Owen" =>15},
# {"Qasim"=>1, "Kaka" =>20}]