Как отсортировать данный список массивов? - PullRequest
1 голос
/ 11 апреля 2019
list = ["HM00", "HM01", "HM010", "HM011", "HM012", "HM013", "HM014", "HM015", "HM016", "HM017", "HM018", "HM019", "HM02", "HM020", "HM021", "HM022", "HM023", "HM024", "HM025", "HM026", "HM027", "HM028", "HM029", "HM03", "HM030", "HM031", "HM032", "HM033", "HM034", "HM035", "HM036", "HM037", "HM038", "HM039", "HM04", "HM040", "HM041", "HM042", "HM043", "HM044", "HM045", "HM046", "HM047", "HM05", "HM06", "HM07", "HM08", "HM09"]

Я хочу, чтобы результаты отображались как ["HM00", "HM01", "HM002" ...], но используя метод сортировки, он дает следующие результаты

["HM00", "HM01", "HM010", "HM011", "HM012", "HM013", "HM014", "HM015", "HM016", "HM017", "HM018", "HM019", "HM02"]

Ответы [ 2 ]

5 голосов
/ 11 апреля 2019

Если каждый элемент имеет номер в конце

list.sort_by { |item| item.scan(/\d*$/).first.to_i }

сопоставить это число в конце, взять первое (потому что сканирование дает массив результатов), преобразовать его в целое число

простой

list.sort_by { |item| item[/\d*$/].to_i }

[] уже принимает первый матч

0 голосов
/ 15 апреля 2019

Существует более общее решение, которое будет работать с большинством строк, которые содержат группы чисел

number = /([+-]{0,1}\d+)/;

strings = [ '2', '-2', '10', '0010', '010', 'a', '10a', '010a', '0010a', 'b10', 'b2', 'a1b10c20', 'a1b2.2c2' ]

p strings.sort_by { |item| [item.split(number).each_slice(2).map {
  |x| x.size == 1 ? [ x[0], '0' ] : [ x[0], x[1] ] }].map {|y| ret = y.inject({r:[],x:[]}) { |s, z| s[:r].push [ z[0], z[1].to_r]; s[:x].push z[1].size.to_s; s }; ret[:r] + ret[:x] }.flatten
}

Вы можете настроить number в соответствии с типами чисел, которые вы хотите использовать: целые числа, числа с плавающей запятойи т. д.

Существует некоторый дополнительный код для сортировки одинаковых чисел по длине, так что «10» предшествует «010».

...