Я рекомендую использовать sort_by
с пользовательским блоком, который находит позицию элемента в новом массиве.
new_array = some_object[:some_array].sort_by do |item|
order = target_order.detect { |order| order[:id] == item[:id] }
next unless order
order[:new_position]
end
Возвращает следующее значение.
=> [{:id=>"foo2"}, {:id=>"foo1"}, {:id=>"foo0"}, {:id=>"foo3"}]
Дополнительные соображения
Возможно, вы хотели назначить каждому элементу позицию в списке, а не просто сортировать их. Например
target_order = [
{ id: "foo0", new_position: 0 },
{ id: "foo1", new_position: 2 }
]
даст
=> [{ id: "foo0" }, nil, { id: "foo1" }]
Для этого следует использовать each_with_object
вместо sort_by
.
new_array = target_order.each_with_object([]) do |order, memo|
item = some_object[:some_array].detect { |item| item[:id] == order[:id] }
next unless item
memo[order[:new_position]] = item
end