Angelo
Angelo

Reputation: 7

Sort an array based on a substring in the array element

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

Answers (2)

ikegami
ikegami

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

choroba
choroba

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

Related Questions