#perl #sorting #substring
#perl #сортировка #подстрока
Вопрос:
Есть ли способ, которым я могу отсортировать массив на основе вложенной строки элемента массива. Например, допустим, у меня есть следующий массив:
@myArray = qw("AAA|111|bbb" "CCC|333|ddd" "EEE|444|fff" "GGG|222|hhh");
Я хочу отсортировать этот массив на основе вложенной строки, начинающейся с позиции 4 (на основе нуля), длиной 3 (в первом элементе массива в моем примере это было бы «111»).
Длина каждого элемента массива всегда будет одинаковой для всех элементов, а вложенная строка, по которой я хочу выполнить сортировку, всегда будет находиться в одной и той же позиции при одинаковой длине в элементе массива.
Вот как будет выглядеть мой отсортированный вывод:
AAA|111|bbb
GGG|222|hhh
CCC|333|ddd
EEE|444|fff
Кроме того, хотя я показываю числа в качестве подстроки в моем примере, там также могут быть нечисловые значения. Таким образом, сортировка должна была бы работать и для не-чисел.
Ответ №1:
сортировка может принимать первый параметр, представляющий собой блок кода, который сравнивает два элемента:
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
my @myArray = qw( AAA|111|bbb CCC|333|ddd EEE|444|fff GGG|222|hhh );
say for sort { substr($a, 4, 3) cmp substr($b, 4, 3) } @myArray;
Смотрите также substr.
Обратите внимание, что я удалил двойные кавычки из qw()
. «qw» означает «слова в кавычках», поэтому кавычки не нужны (фактически, они были бы частью строк, а это не то, что вы хотели).
Используя модуль Sort::Key, это может стать еще проще:
use Sort::Key qw{ keysort };
...
say for keysort { substr $_, 4, 3 } @myArray;
Ответ №2:
Какая польза от каналов, если это запись полей фиксированной длины?
Если бы вы обрабатывали входные данные как значения, разделенные каналами, тогда ваш код стал бы
say for sort { ( split /|/, $a )[1] <=> ( split /|/, $b )[1] } @myArray;
и
use Sort::Key qw( ikeysort );
say for ikeysort { ( split /|/ )[1] } @myArray;
[Это не должно быть полным ответом, а расширением choroba’s.]
Комментарии:
1. Спасибо, Чороба, я опробую ваш код и свяжусь с вами. икегами, я не предполагал, что элемент массива будет напоминать запись фиксированной длины, но ты прав, теперь это так, и я могу удалить каналы. Я был так увлечен написанием своего кода, что не понял, что произошло. Спасибо за предупреждение. Анджело
2. Вы найдете
pack "a3 a3 a3"
иunpack "a3 a3 a3"
полезные