Сортировка массива на основе подстроки в элементе массива

#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" полезные