Я хочу отсортировать массив по строкам сначала и затем числам. Как я делаю это?
Общий трюк для решения хитрых сортов заключается в использовании #sort_by, при этом блок возвращает массив, имеющий первичный и вторичный порядок сортировки (а, если нужно, третичный и т.д.)
a = ['foo', 'bar', '1', '2', '10']
b = a.sort_by do |s|
if s =~ /^\d+$/
[2, $&.to_i]
else
[1, s]
end
end
p b # => ["bar", "foo", "1", "2", "10"]
Это работает, так как способ сравнения массивов определяется Ruby. Сравнение определяется методом Array#<=>:
Массивы сравниваются "по элементам"; первый элемент ary сравнивается с первым из других_ary с помощью оператора <=>, затем с каждым из вторых элементов и т.д.... Как только результат любого такого сравнения становится ненулевым (i. e. два соответствующих элемента не равны), этот результат возвращается для всего сравнения массива.
Отсортируйте массив смешанных чисел и строк, поместив числа сначала по порядку, затем по порядку, затем по строкам.
>> a = [1, 2, "b", "a"]
>> a.partition{|x| x.is_a? String}.map(&:sort).flatten
=> ["a", "b", 1, 2]
Обычно алфавитизация выполняется сначала с числами. Если вы хотите алфавитировать что-то, где буквы расположены в алфавитном порядке перед цифрами, вам нужно изменить используемую функцию сравнения.
# I realize this function could be done with less if-then-else logic,
# but I thought this would be clearer for teaching purposes.
def String.mysort(other)
length = (self.length < other.length) ? self.length : other.length
0.upto(length-1) do |i|
# normally we would just return the result of self[i] <=> other[i]. But
# you need a custom sorting function.
if self[i] == other[i]
continue # characters the same, skip to next character.
else
if self[i] ~= /[0-9]/
if other[i] ~= /[0-9]/
return self[i] <=> other[i] # both numeric, sort normally.
else
return 1 # self is numeric, other is not, so self is sorted after.
end
elsif other[i] ~= /[0-9]/
return -1 # self is not numeric, other is, so self is sorted before.
else
return self[i] <=> other[i] # both non-numeric, sort normally.
end
end
end
# if we got this far, the segments were identical. However, they may
# not be the same length. Short sorted before long.
return self.length <=> other.length
end
['0','b','1','a'].sort{|x,y| x.mysort(y) } # => ['a', 'b', '0', '1']
Если вы пытаетесь отсортировать Смешанный регистр и числа, только несколько человек на земле могут делать это вне несвободных приложений. Это секрет с помощью сосунка. Вы должны использовать qsort, который облегчает сортировку до тех пор, пока вы не смешаете регистры (заглавные и строчные буквы). Затем колледж, книги и интернет оставляют вас в подвешенном состоянии. Этот хакер стоит своего веса в золоте и является латунным кольцом программирования по всем причинам.
Чтобы сортировать числа словами, вы должны преобразовывать числа в строку. Вы должны предварительно сортировать, используя верхний регистр. Если у вас есть слова "Ant", "Ant" и "anT", то все они должны указывать на слово "ANT" в списке сортировки в верхнем регистре. Затем вы создадите список (массив) только из этих трех слов ["Ant", "Ant" и "anT"]. и использовать qsort в качестве прерывателя связей для их сортировки.
Затем вы вставляете их в конечный массив сортировки. Это довольно сложно по конструкции. "A" - 65 на ascii и "a" - 97 с большим количеством символов мусора между 'Z' и 'a'! Это не случайно! Говорю вам, это заговор!
Можно создать сортировочную таблицу, чтобы более разумно сгруппировать такие символы, как:
A, a, B, b, C, c, D, d, E, e, F, f, G, g, H, h, I, i, J, j, K, k, L, l, M, m, N, n, .... 65 66 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 87 89 90 91 92 ...
построение таблицы вокруг этого блока, начиная с "(пробел) ascii 32 до 128. вы, вероятно, захотите переупорядочить числа в последовательности, в которой, например, только A 65.
Это облегчает задачу, но, скорее всего, приведет к тому, что хит производительности окажется за пределами макросов большинства языков программирования. Удачи!
Вот несколько подробный ответ. Разделите массив на два подмассива: строки и числа, отсортируйте их и объедините.
array = [1, 'b', 'a', 'c', 'd', 2, 4, 3]
strings = []
numbers = []
array.each do |element|
if element.is_a? String
strings << element
else
numbers << element
end
end
sorted_array = strings.sort + numbers.sort
sorted_array # ['a', 'b', 'c', 'd', 1, 2, 3, 4]