Reputation: 7
Is there a way that I can sort an array based on a sub-string of the array element. For example, lets say I have the following array:
@myArray = qw("AAA|111|bbb" "CCC|333|ddd" "EEE|444|fff" "GGG|222|hhh");
I want to sort this array based on the sub-string starting at position 4 (zero-based) for a length of 3 (in the first array element in my example, that would be "111").
The length of each array element will always be the same for all elements and the sub-string I want to sort on will always be in the same position for the same length in the array element.
This is what my sorted output would look like:
AAA|111|bbb
GGG|222|hhh
CCC|333|ddd
EEE|444|fff
Also, while I am showing numbers as the sub-string in my example, it could be non-number values in there too. So the sort would have to work for non-numbers too.
Upvotes: 0
Views: 353
Reputation: 385590
What's the use of pipes if this is a record of fixed-length fields?
If you were to treat the input as pipe-separated values, then your code would become
say for sort { ( split /\|/, $a )[1] <=> ( split /\|/, $b )[1] } @myArray;
and
use Sort::Key qw( ikeysort );
say for ikeysort { ( split /\|/ )[1] } @myArray;
[This is not meant to be a complete answer, but an extension of choroba's.]
Upvotes: 0
Reputation: 241808
sort can take the first parameter that is a code block that compares two elements:
#!/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;
See also substr.
Note that I removed the double quotes from the qw()
. "qw" stands for "quote words", so no quotes are needed (in fact, they would be part of the strings which isn't what you wanted).
Using the Sort::Key module, it can get even simpler:
use Sort::Key qw{ keysort };
...
say for keysort { substr $_, 4, 3 } @myArray;
Upvotes: 1