2015-02-08 3 views
1

У меня есть массив хэш, как указано ниже:Сортировка массива хэш на основе массива отсортированных значений

user_quizzes = [{:id => 3897, :quiz_id => 1793, :user_id => 252}, {:id => 3897, :quiz_id => 1793, :user_id => 475}, {:id => 3897, :quiz_id => 1793, :user_id => 880}, {:id => 3897, :quiz_id => 1793, :user_id => 881}, {:id => 3897, :quiz_id => 1793, :user_id => 882}, {:id => 3897, :quiz_id => 1793, :user_id => 883}, {:id => 3897, :quiz_id => 1793, :user_id => 884}] 

Кроме того, на основе определенного состояния я принял значение ключа «user_id» из тот же хэш и сортирует его и тот же массив приведен ниже:

sorted_user_ids = [880, 881, 882, 883, 884, 475, 252] 

Теперь я нужен user_quizzes быть перестроен на основе порядка user_id в sorted_user_ids массиве.

Может кто-нибудь, пожалуйста, помогите мне в этом. :)

ответ

3

Использование Enumerable#sort_by или Array#sort_by!, вы можете указать ключ, который будет использоваться для сравнения:

user_quizzes = [ 
    {:id => 3897, :quiz_id => 1793, :user_id => 252}, 
    {:id => 3897, :quiz_id => 1793, :user_id => 475}, 
    {:id => 3897, :quiz_id => 1793, :user_id => 880}, 
    {:id => 3897, :quiz_id => 1793, :user_id => 881}, 
    {:id => 3897, :quiz_id => 1793, :user_id => 882}, 
    {:id => 3897, :quiz_id => 1793, :user_id => 883}, 
    {:id => 3897, :quiz_id => 1793, :user_id => 884} 
] 
sorted_user_ids = [880, 881, 882, 883, 884, 475, 252] 
user_quizzes.sort_by { |x| sorted_user_ids.index(x[:user_id]) } 
# => [{:id=>3897, :quiz_id=>1793, :user_id=>880}, 
#  {:id=>3897, :quiz_id=>1793, :user_id=>881}, 
#  {:id=>3897, :quiz_id=>1793, :user_id=>882}, 
#  {:id=>3897, :quiz_id=>1793, :user_id=>883}, 
#  {:id=>3897, :quiz_id=>1793, :user_id=>884}, 
#  {:id=>3897, :quiz_id=>1793, :user_id=>475}, 
#  {:id=>3897, :quiz_id=>1793, :user_id=>252}] 

Side Примечание: sorted_user_ids.index(x[:user_id]) может стать узким местом (повтор O (п) операций), если массив огромно.

построить хэш, который отображает user_id с для заказов в таком случае:

sorted_user_ids = [880, 881, 882, 883, 884, 475, 252] 
order = Hash[sorted_user_ids.each_with_index.to_a] 
# => {880=>0, 881=>1, 882=>2, 883=>3, 884=>4, 475=>5, 252=>6} 
user_quizzes.sort_by { |x| order[x[:user_id]] } 
# => same as above. 
+0

В данном случае 'user_quizzes.sort {| а, б | a [: user_id] <=> b [: user_id]} 'является более читаемым и простым в обслуживании. Хотя я понимаю штрафы за время исполнения. – mudasobwa

+0

@mudasobwa, OP хотят заказать 'sorted_user_ids', а не' user_id': ** ... перестроены в соответствии с порядком 'user_id' в массиве' sorted_user_ids'. ** – falsetru

+0

О, да, вы правы , Прости. – mudasobwa

Смежные вопросы