2014-02-10 4 views
1

У меня есть массив хешей, id является одним из ключей в хешах. Я хочу отсортировать элементы массива в соответствии с заданным порядком значений ID.Ruby: Как отсортировать массив хэшей в заданном порядке определенного ключа

Пусть мой массив (размер = 5):

[{"id"=>1. ...}, {"id"=>4. ...}, {"id"=>9. ...}, {"id"=>2. ...}, {"id"=>7. ...}] 

Я хочу, чтобы отсортировать элементы массива таким образом, что их id s в следующем порядке:

[1,3,5,7,9,2,4,6,8,10] 

Так что ожидаемый результат is:

[{'id' => 1},{'id' => 7},{'id' => 9},{'id' => 2},{'id' => 4}] 

ответ

3

Вот решение для любого специального индекса:

def my_index x 
    # Custom code can be added here to handle items not in the index. 
    # Currently an error will be raised if item is not part of the index. 
    [1,3,5,7,9,2,4,6,8,10].index(x) 
end 

my_collection = [{"id"=>1}, {"id"=>4}, {"id"=>9}, {"id"=>2}, {"id"=>7}] 
p my_collection.sort_by{|x| my_index x['id'] } #=> [{"id"=>1}, {"id"=>7}, {"id"=>9}, {"id"=>2}, {"id"=>4}] 

Затем вы можете отформатировать его в любом случае вы хотите, может быть, это похорошела:

my_index = [1,3,5,7,9,2,4,6,8,10] 
my_collection.sort_by{|x| my_index.index x['id'] } 
1

Общее примечание по сортировке. Используйте #sort_by метод класса «s:

[{'id' => 1},{'id'=>3},{'id'=>2}].sort_by {|x|x['id'] } 
# => [{"id"=>1}, {"id"=>2}, {"id"=>3}] 

Или с использованием #values Способ обратного вызова:

[{'id' => 1},{'id'=>3},{'id'=>2}].sort_by(&:values) 
# => [{"id"=>1}, {"id"=>2}, {"id"=>3}] 

или вы можете использовать более очевидный вариант с #sort методом:

[{'id' => 1},{'id'=>3},{'id'=>2}].sort {|x,y| x['id'] <=> y['id'] } 
# => [{"id"=>1}, {"id"=>2}, {"id"=>3}] 

Для вашего случая, для сортировки с расширенным условием используйте #%, чтобы разделить ev еп и нечетные индексы:

[{'id' => 1},{'id'=>4},{'id'=>9},{'id'=>2},{'id'=>7}].sort do |x,y| 
    u = y['id'] % 2 <=> x['id'] % 2 
    u == 0 && y['id'] <=> x['id'] || u 
end 
# => [{"id"=>1}, {"id"=>7}, {"id"=>9}, {"id"=>2}, {"id"=>4}] 

В вашем случае, чтобы разобраться с расширенным условия использования #% разделить по индексу, даже id значение отсутствует в массиве индекса:

index = [1,3,5,7,4,2,6,8,10] # swapped 2 and 4, 9 is absent 

[{'id' => 1},{'id'=>4},{'id'=>9},{'id'=>2},{'id'=>7}].sort do |x,y| 
    !index.rindex(x[ 'id' ]) && 1 || index.rindex(x[ 'id' ]) <=> index.rindex(y[ 'id' ]) || -1 
end 
# => [{"id"=>1}, {"id"=>7}, {"id"=>4}, {"id"=>2}, {"id"=>9}] 
+0

@ монах-кода Thanx =) –

+0

Ожидаемый результат является '[{ 'ID' => 1}, { 'ID' => 7}, { 'ID' => 9}, { 'id' => 2}, {'id' => 4}] ' – nish

+0

@ Малъ я люблю чистые решения. –

1

Я бы карту хэш на основе значений, как так:

a = [{"id"=>1}, {"id"=>4}, {"id"=>9}, {"id"=>2}, {"id"=>7}] 

[1,3,5,7,9,2,4,6,8,10].map{|x| a[a.index({"id" => x})] }.compact 

#=> [{"id"=>1}, {"id"=>7}, {"id"=>9}, {"id"=>2}, {"id"=>4}] 
0

Почему просто не sort?

def doit(arr, order) 
    arr.sort { |h1,h2| order.index(h1['id']) <=> order.index(h2['id']) } 
end 

order = [1,3,5,7,9,2,4,6,8,10] 
arr = [{'id' => 1}, {'id' => 4}, {'id' => 9}, {'id' => 2}, {'id' => 7}]  

doit(arr, order) 
    #=> [{'id' => 1}, {'id' => 7}, {'id' => 9}, {'id' => 2}, {'id' => 4}]  
0
a= [{"id"=>1}, {"id"=>4}, {"id"=>9}, {"id"=>2}, {"id"=>7}] 
b=[1,3,5,7,9,2,4,6,8,10] 
a.sort_by{|x| b.index (x['id'])} 
Смежные вопросы