2012-03-18 3 views
1

У меня есть массив [5, 3, 1, 4] который соответствует хэш-ключей производится следующим кодом:Сортировка многомерного массива на основе второго массива в Рубине

@ordered_hash = Review.group('aidmodel_id').average('score') 
@ordered_hash = ActiveSupport::OrderedHash[@ordered_hash.sort_by {|key, value| value }] 
@keys = @ordered_hash.keys 

Используя ключи, полученные @keys = [5, 3, 1, 4] Я хотел бы, чтобы вытащить некоторые записи из моя база данных использует:

@reviews = Review.where(:aidmodel_id=>@keys).uniq_by {|x| x.aidmodel_id} 

Это хорошо работает. Однако возвращаемые модели находятся в том порядке, в котором они отображаются в базе данных, а не в порядке, указанном ключами. Это означает, что результат сортируется случайным образом, а не в порядке среднего балла.

Должен быть какой-то способ переупорядочить многомерный массив, возвращенный системой Review.where на основе массива @keys .. или каким-то образом вывести записи в правильном порядке .. возможно, используя цикл вокруг SQL запрос?

Спасибо за помощь!

+0

«возвращенные модели находятся в том порядке, в котором они отображаются в базе данных», не совсем верно, в базе данных нет порядка, если вы явно не заказываете BY. –

+0

К сожалению, я имею в виду порядок их идентификаторов – Abram

ответ

1

Вы можете оптимизировать свои первые два оператора, чтобы использовать сортировку БД, как рельсы групповые функции return OrderedHash

# you can order the result set by the select col position instead of name 
avg_scores = Review.average(:score, :group => :aidmodel_id, :order => "2 ASC") 
# assuming you don't have 100s of rows here.. 
rh = Review.where(:aidmodel_id=> @avg_scores.keys).group_by(&:aidmodel_id) 
avg_score_set = avg_scores.map {|id, score| [id, score, rh[id]]} 

Теперь avg_score_set - это упорядоченный массив массивов. Внутренний массив имеет оценку и обзоры.

+0

'.average' возвращает объект OrderedHash, а не объект отношения. Ура для согласованных интерфейсов! –

+0

@muistooshort, вы правы, я обновил свой ответ, чтобы решить эту проблему. –

+0

В конечном итоге таблица будет содержать 100 строк. Как вы думаете, реализация вышеуказанного кода будет представлять собой риск? Благодарю. – Abram

1

Я не знаю, о Ruby, но в PostgreSQL вы можете получить элементы массива в запрашиваемом порядке, как это:

SELECT arr[i] AS arr_element 
FROM (SELECT '{1,2,3,4,5}'::int[] AS arr, unnest(ARRAY[5, 3, 1, 4]) AS i) x 
+0

Thanks Erwin. Какова релевантность {1,2,3,4,5} в вашем коде выше? – Abram

+1

@Abram: ''{1,2,3,4,5}' :: int []' является одним из нескольких способов ввода литерала массива. Другим может быть: «ARRAY [1,2,3,4,5]». [Подробнее об этом в руководстве] (http://www.postgresql.org/docs/9.1/static/arrays.html#ARRAYS-INPUT). –

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