2013-11-08 7 views
2

sort_by_this_array = [4,2,1,3] < - Это массив атрибута goal_id.Сортировка по массиву идентификаторов RUBY

& тогда у меня есть

[<Todo id: 12, goal_id: 2]>, <Todo id: 13, goal_id: 2>, <Todo id: 6, goal_id: 1>, <Todo id: 7, goal_id: 2 >, <Todo id: 25, goal_id: 3 >, <Todo id: 30, goal_id: 1 >, <Todo id: 40, goal_id: 4 >] 

Результат должен быть: ID: 40, 12,13,7, 6,30, 25

Я думаю о 2 петли & это, безусловно, не лучший путь.

+1

возможно дубликат [Сортировка массива объектов в Ruby, с помощью атрибута объекта] (http://stackoverflow.com/questions/882070/ sorting-a-array-of-objects-in-ruby-by-object-attribute) –

+0

Благодарим вас за ответ. Похоже, что он сортируется в порядке ASC. sort_by (&: goal_id). Мне нужно немного другое. Я немного изменил свой вопрос, может ли он стать яснее. – whitesiroi

+0

какой заказ? – Nithin

ответ

5

Может попробовать этот подход:

S = Struct.new(:id, :v) 
a = Array.new(5) { |i| S.new(i, i) } 
a.shuffle! 
a.sort_by {|e| [2, 3 , 1 , 4, 0].index(e.id) } 

Он возвратит ваши a в порядке идентификаторов.

+0

Awesome. Большое спасибо. Он работает отлично. – whitesiroi

1

Возможно, вы захотите использовать сортировку по выбору, где будет происходить обмен, каждый раз, когда вы найдете элемент «todo», для которого его атрибут «goal_id» равен «goal_id» из вашего массива.

Todo = Struct.new(:id, :goal_id) 
todos = [Todo.new(12,2), Todo.new(13,2),Todo.new(6,1), Todo.new(7,2), Todo.new(25,3), Todo.new(30,1), Todo.new(40,4)] 
sort_by_this_array = [4,2,1,3] 

j = 0 
sort_by_this_array.each do |goal_id| 
    todos.each_with_index do |todo,i| 
    if todo.goal_id == goal_id 
     todos[i],todos[j] = todos[j],todos[i] 
     j += 1 
    end 
    end 
end 

Я бы рекомендовал прочитать некоторые источники в Интернете о сортировке по выбору. Так как это его простой вариант http://www.sorting-algorithms.com/selection-sort

К сожалению, это решение не сохранит порядок элементов внутри исходного массива todos, так как каждая замена меняет положение, на котором расположен элемент todo. Поэтому они будут отсортированы, но это будет нестабильно.

Ниже стабильного решения с дополнительной памятью.

j = 0 
results = [] 
sort_by_this_array.each do |goal_id| 
    while idx = todos.index {|e| e.goal_id == goal_id} 
    results << todos[idx] 
    todos.delete_at(idx) 
    end 
end 
+0

Большое спасибо. Две петли :) Я сделал это тоже с двумя петлями, но после ответа Игоря Касьянчука я ... :) Спасибо, ребята, за помощью. – whitesiroi

+0

Вы должны знать, что с помощью 'a.sort_by {| e | [2, 3, 1, 4, 0] .index (e.id)} 'не сохранит начальный порядок, а в некоторых случаях использование sort_by может быть просто неэффективным. Для получения дополнительной информации я бы предложил прочитать информацию на следующем сайте: http://apidock.com/ruby/Enumerable/sort_by. Иногда один лайнер не лучший вариант (с точки зрения производительности), но это очень зависит от вашего варианта использования. –

+0

Большое спасибо за помощь. – whitesiroi

0

Вы можете попробовать это:

Todo.all.sort_by{|e| e[:goal_id]} 

Проверить это post

+1

Спасибо, товарищ :) – whitesiroi

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