Строки вида и числа в Ruby

Я хочу отсортировать массив по строкам сначала и затем числам. Как я делаю это?

5
задан Sasha Chedygov 26 December 2009 в 22:27
поделиться

5 ответов

Общий трюк для решения хитрых сортов заключается в использовании #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. два соответствующих элемента не равны), этот результат возвращается для всего сравнения массива.

15
ответ дан 18 December 2019 в 05:23
поделиться

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

>> a = [1, 2, "b", "a"]

>> a.partition{|x| x.is_a? String}.map(&:sort).flatten
=> ["a", "b", 1, 2]
17
ответ дан 18 December 2019 в 05:23
поделиться

Обычно алфавитизация выполняется сначала с числами. Если вы хотите алфавитировать что-то, где буквы расположены в алфавитном порядке перед цифрами, вам нужно изменить используемую функцию сравнения.

# 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']
2
ответ дан 18 December 2019 в 05:23
поделиться

Если вы пытаетесь отсортировать Смешанный регистр и числа, только несколько человек на земле могут делать это вне несвободных приложений. Это секрет с помощью сосунка. Вы должны использовать 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.

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

0
ответ дан 18 December 2019 в 05:23
поделиться

Вот несколько подробный ответ. Разделите массив на два подмассива: строки и числа, отсортируйте их и объедините.

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]
1
ответ дан 18 December 2019 в 05:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: