2016-01-15 9 views
9

Я пытаюсь сортировать массив со смесью ints и строк. Возьмем, к примеру:Как отсортировать массив целых чисел и строк?

a = ["a", "b", 5, "c", 4, "d", "a1", "a12", 3, 13, 2, "13a", "12a"] 

Я пробовал:

a.sort do |x, y| 
    if x.class == y.class 
    x <=> y 
    else 
    x.class.to_s <=> y.class.to_s 
    end 
end 

Который возвращает:

[2, 3, 4, 5, 13, "12a", "13a", "a", "a1", "a12", "b", "c", "d"] 

Результат я хочу это:

[2, 3, 4, 5, "12a", 13, "13a", "a", "a1", "a12", "b", "c", "d"] 
+0

Может ли быть несколько строк в ваших строках, например ' "A1B2C3"'? – Stefan

+0

Что случилось? '[" a1 "," a12 "," a2 "]' или '[" a1 "," a2 "," a12 "]'? – Stefan

+0

@Stefan Возможно иметь более одного номера в строке. Последняя «[a1», «a2», «a12»] ' –

ответ

11
a.sort_by { |x| [(x.to_s.match(/^\d+/) ? x.to_i : 1.0/0), x.to_s] } 

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


EDIT: Как О.П. пояснил, что он хочет, чтобы рассмотреть не только ведущее числовое значение, но все, что следует, мы можем использовать ту же самую идею, только на этот раз мы должны применять его на каждом человек числовой и нецифровой объект в строке:

a.sort_by do |x| 
    x.to_s.split(/(\D+)/).map do |y| 
    [(y.match(/\d/) ? y.to_i : 1.0/0), y] 
    end 
end 
+1

«0» в массиве попадет между «13a» и «a» « – Stefan

+0

@Stefan, обновлен. – ndn

+0

Это лучше, но он не сортирует '[" a13 "," a2 "]' правильно. – Stefan

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