我有一个这样的数组
@uniqarr = qw(error 0 goodrecordno:6123, error 0 goodrecordno:6143, error 1 goodrecordno:10245, error 1 goodrecordno:10678, error 1 goodrecordno:10698, error 2 goodrecordno:16245, error 2 goodrecordno:16123);
我希望o / p为
error 0 goodrecordno:6123
error 1 goodrecordno:10245
error 2 goodrecordno:16123
即每次错误一次及其对应的最低记录。 任何人都可以帮助我而不使用cpan模块
提前致谢。
答案 0 :(得分:3)
这是您在开始Perl书籍时可以找到的基本最小 - 最大问题。你可以通过所有元素,并记住哪一个是最低的。这比排序要好得多,排序是为了让你按顺序排列所有元素,这不是你想要的。
use strict;
use warnings;
# I'll assume those commas were a mistake. You don't need to separate
# items with commas in a quotewords list
# If I'm wrong, the process is the same although the data massaging
# will be a little different
my @elements = qw(
error 0 goodrecordno:6123
error 0 goodrecordno:6143
error 1 goodrecordno:10245
error 1 goodrecordno:10678
error 1 goodrecordno:10698
error 2 goodrecordno:16245
error 2 goodrecordno:16123
);
my %lowest;
while( my( $error, $number, $goodrecno ) = splice @elements, 0, 3, () )
{
my( $recno ) = $goodrecno =~ /(\d+)/;
# This hash remembers the lowest $recno. If you find another
# a lower number, you replace the previous value.
$lowest{$number} = $recno if(
! exists $lowest{$number}
||
$recno < $lowest{$number}
);
}
一旦你创建了具有最低元素的哈希,你只需打印它:
foreach my $number ( sort { $a <=> $b } keys %lowest ) {
print "error $number goodrecordno:$lowest{$number}\n";
};
这可以为您提供所需的输出:
error 0 goodrecordno:6123
error 1 goodrecordno:10245
error 2 goodrecordno:16123
这是针对这些问题的基本模板。第1步:扫描数据以记住您想要的内容,使用哈希来键入这些数据。第2步:输出哈希的内容。
答案 1 :(得分:1)
要删除重复项,最好的方法是使用List::MoreUtils的uniq
,:
use List::MoreUtils 'uniq';
my @unique_list = uniq @list;
或没有CPAN(虽然这很少需要):
my %values;
@values{@list} = ();
my @unique_list = keys %values;
您可以使用内置函数排序对任何列表进行排序 - 请参阅perldoc -f sort和perldoc -q 'How do I sort an array'。
顺便提一下,您引用的数据与您描述的行为不符。如果将数组声明为
@uniqarr = qw(error 0 goodrecordno:6123, error 0 goodrecordno:6143, error 1 goodrecordno:10245, error 1 goodrecordno:10678, error 1 goodrecordno:10698, error 2 goodrecordno:16245, error 2 goodrecordno:16123);
...然后其内容将包含:
(
'error',
'0',
'goodrecordno:6123,',
'error',
'0',
'goodrecordno:6143,',
'error',
'1',
'goodrecordno:10245,',
'error',
'1',
'goodrecordno:10678,',
'error',
'1',
'goodrecordno:10698,',
'error',
'2',
'goodrecordno:16245,',
'error',
'2',
'goodrecordno:16123'
);
您需要做的是将数据读入哈希表,然后根据您的标准进行解析。我不能再往前走,因为它一点也不清楚你在寻找什么。请阅读perldoc perldata和perldoc perldsc以了解有关Perl数据结构的更多信息。
答案 2 :(得分:0)
正如其他人已经指出你的第一个问题是qw()
不适合建立这个数组。
有多种方法可以正确地完成它,我将在这里使用一个哈希数组,这是更详细的选项,将技术修改为您选择的任何结构都相当容易。
@uniqarr = (
{ error => 0, goodrecordno => 6123, },
{ error => 0, goodrecordno => 6143, },
{ error => 1, goodrecordno => 10245, },
{ error => 1, goodrecordno => 10678, },
{ error => 1, goodrecordno => 10698, },
{ error => 2, goodrecordno => 16245, },
{ error => 2, goodrecordno => 16123, },
);
然后,使用最低的goodrecordno提取每个错误实例,我们可以执行以下操作。
首先我们从List :: Util导入min。该模块是核心Perl,不需要CPAN。
然后重组输入@uniqarr。我们想要按错误值分组的内容要容易得多。所以by_error是数组的哈希。哈希的关键是错误值,该数组包含所有goodrecordno值。
最后我们产生了所需的输出。循环遍历散列意味着我们迭代每个错误值,排序以提供正确的输出顺序。然后我们提取最小的goodrecordno值。这就是打印输出。
use List::Util qw(min); # In core Perl, not CPAN
# Restructure input
my %by_error; # Hash with error as key, array of goodrecordno as value.
foreach (@uniqarr) {
push @{$by_error{$_->{error}}}, $_->{goodrecordno};
}
# Output as desired
foreach my $error (sort keys %by_error) {
my $min_no = min @{$by_error{$error}};
print "error $error goodrecordno:$min_no\n";
}