2010-05-12 5 views
4

У меня есть массив рубин, который выглядит примерно так:Сортировать конкретные элементы массива первых

my_array = ['mushroom', 'beef', 'fish', 'chicken', 'tofu', 'lamb'] 

Я хочу, чтобы отсортировать массив, так что «курица» и «говядина» первые два пункта, а затем остальные элементы сортируются в алфавитном порядке. Как мне это сделать?

ответ

10
irb> my_array.sort_by { |e| [ e == 'chicken' ? 0 : e == 'beef' ? 1 : 2, e ] } 
#=> ["chicken", "beef", "fish", "lamb", "mushroom", "tofu"] 

Это создаст сортировочный ключ для каждого элемента массива, а затем отсортировать элементы массива по их сортировки ключей. Поскольку ключ сортировки является массивом, он сравнивается по положению, поэтому [0, 'chicken'] < [1, 'beef'] < [2, 'apple' ] < [2, 'banana'].

Если вы не знаете, какие элементы вы хотели сортируетесь на фронт до выполнения, вы можете использовать этот трюк:

irb> promotables = [ 'chicken', 'beef' ] 
    #=> [ 'chicken', 'beef' ] 
irb> my_array.sort_by { |e| [ promotables.index(e) || promotables.size, e ] } 
    #=> ["chicken", "beef", "fish", "lamb", "mushroom", "tofu"] 
irb> promotables = [ 'tofu', 'mushroom' ] 
    #=> [ 'tofu', 'mushroom' ] 
irb> my_array.sort_by { |e| [ promotables.index(e) || promotables.size, e ] } 
    #=> [ "tofu", "mushroom", "beef", "chicken", "fish", "lamb"] 
6

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

my_array = ['mushroom', 'beef', 'fish', 'chicken', 'tofu', 'lamb'] 
starters = ['chicken', 'beef'] 
starters + (my_array.sort - starters) 
# => ["chicken", "beef" "fish", "lamb", "mushroom", "tofu"] 
+0

если 'курица' или 'говядина' встречаются больше (или меньше), чем один раз в 'my_array' тогда результат этого не будет переупорядочением 'my_array'. – rampion

+0

Комментарий Rampion не кажется правильным с Ruby 2.2.2 на момент написания. – Scott

1

Другой способ решить эту проблему:

array = [1,2,2,3,3,4,5] 
array.select {|element| element == 2} + array.select {|element| element != 2} 
# => [2, 2, 1, 3, 3, 4, 5] 
1

Может просто сделать

firsts = ["chicken", "beef"] 
[*firsts, *(my_array.sort - firsts)] 

#=> ["chicken", "beef", "fish", "lamb", "mushroom", "tofu"] 
Смежные вопросы