Dav*_*d B 2 arrays sorting perl
我有一些长度相同的数组.我想对第一个数组进行排序,并使所有其他数组相应地"排序".例如,如果第一个数组是(7,2,9)第二个是("seven","two","nine"),第三个数组是在("VII","II","IX")排序之后(根据第一个数组值递增),我们将拥有(2,7,9) ("two","seven","nine")和("II","VII","IX").
我怎样才能做到这一点?
hob*_*bbs 17
虽然我同意eugene y和MvanGeest通常最好的答案是切换到另一个数据结构,但有时您可能需要并行数组(或者至少可能无法避免它们),并且实际上有一种方法可以并行排序数组并行.它是这样的:
my @nums = (7, 2, 9);
my @names = qw(seven two nine);
my @roman = qw(VII II IX);
my @sorted_indices = sort { $nums[$a] <=> $nums[$b] } 0..$#nums;
@$_ = @{$_}[@sorted_indices] for \(@nums, @names, @roman);
Run Code Online (Sandbox Code Playgroud)
也就是说,生成一个与所有数组相对应的索引列表,然后根据将"主"数组按顺序排列的顺序对它们进行排序.获得索引的排序列表后,重新排序所有数组以匹配.
最后一行可以用手写出来
@nums = @nums[@sorted_indices];
@names = @names[@sorted_indices];
@roman = @roman[@sorted_indices];
Run Code Online (Sandbox Code Playgroud)
但我试图减少必要的复制粘贴量,即使是以一些略带毛茸茸的语法为代价.你知道的越多...
我知道你已经接受了答案,这里有其他非常好的答案,但我会提出一些不同的建议:不要复制你的数据.你只需要跟踪阿拉伯语 - >罗马映射一次 - 为什么存储基本上是重复的数字数组,并对每一个进行排序?只需对主列表进行排序,并根据需要在参考数组中查找其他值:
my @roman = qw(0 I II III IV V VI VII VIII IX X);
my @text = qw(zero one two three four five six seven eight nine ten);
my @values = (7, 2, 9);
my @sorted_values = sort @values;
my @sorted_roman = map { $roman[$_] } @sorted_values;
my @sorted_text = map { $text[$_] } @sorted_values;
use Data::Dumper;
print Dumper(\@sorted_values, \@sorted_roman, \@sorted_text);
Run Code Online (Sandbox Code Playgroud)
打印:
$VAR1 = [
2,
7,
9
];
$VAR2 = [
'II',
'VII',
'IX'
];
$VAR3 = [
'two',
'seven',
'nine'
];
Run Code Online (Sandbox Code Playgroud)
在真实环境中,我建议使用库为您执行罗马和文本转换:
use Roman;
my @sorted_roman = map { roman($_) } @sorted_values;
use Lingua::EN::Numbers 'num2en';
my @sorted_text = map { num2en($_) } @sorted_values;
Run Code Online (Sandbox Code Playgroud)
将数据重新组织到单个数组以进行排序:
my @a = ([7, "seven", "VII"], [2, "two", "II"], ..);
@a = sort { $a->[0] <=> $b->[0] } @a;
Run Code Online (Sandbox Code Playgroud)
然后重新创建原始数组:
my(@a1, @a2, @a3);
for (@a) {
push @a1, shift @$_;
push @a2, shift @$_;
push @a3, shift @$_;
}
Run Code Online (Sandbox Code Playgroud)