我有一个包含以下元素的数组:
my @array = ("\"Foo in Bar\" on Mon 09 Feb 2015 08:07:44 AM PST",
"\"Foo in Bar\" on Mon 09 Feb 2015 08:07:47 AM MST",
"\"Foo in Bar\" on Mon 09 Feb 2015 08:07:49 AM MST",
"\"Apple in Pie\" on Mon 09 Feb 2015 10:22:32 AM MST",
"\"Foo in Bar\" on Mon 09 Feb 2015 08:07:51 AM MST",
"\"Rock in Out\" on Mon 09 Feb 2015 11:17:41 AM PST")
我想对这个数组进行排序,以便删除所有带有重复字符串的元素(在""内)。这有点独特的原因是因为与每个字符串相关的时间略有不同,但并不多。
这就是我希望输出看起来像:
"\"Foo in Bar\" on Mon 09 Feb 2015 08:07:49 AM MST",
"\"Apple in Pie\" on Mon 09 Feb 2015 10:22:32 AM MST",
"\"Rock in Out\" on Mon 09 Feb 2015 11:17:41 AM PST"
我不太关心时间的排序,只是删除了""中的重复。
到目前为止,这是我的思考过程:
my @row;
foreach my $row (@array) {
my $name = $row;
$name =~ s/\son.*//;
next if (grep {$_ =~ /($name)/} @row);
push(@row,$row);
}
必须有更好的方法来做到这一点。另外,我的方法有问题(grep似乎没有按预期工作,它不会进入下一个语句。)
答案 0 :(得分:5)
以下内容为@filtered
my %seen;
my @filtered = grep { !$seen{$_}++ } @array;
在您的情况下,需要一个小小的调整。引号之间的子字符串决定了您是否已经看过该项目,因此需要使用它来代替$_
。
my %seen;
my @filtered = grep { /^"([^"]+)"/ && !$seen{$1}++ } @array;
答案 1 :(得分:2)
对于重复检测,哈希是作业的工具。
#!/usr/bin/perl
use strict;
use warnings;
my @array = (
"\"Foo in Bar\" on Mon 09 Feb 2015 08:07:44 AM PST",
"\"Foo in Bar\" on Mon 09 Feb 2015 08:07:47 AM MST",
"\"Foo in Bar\" on Mon 09 Feb 2015 08:07:49 AM MST",
"\"Apple in Pie\" on Mon 09 Feb 2015 10:22:32 AM MST",
"\"Foo in Bar\" on Mon 09 Feb 2015 08:07:51 AM MST",
"\"Rock in Out\" on Mon 09 Feb 2015 11:17:41 AM PST"
);
my %seen;
foreach my $element (@array) {
my ($first_bit) = ( $element =~ m/^(.*) on/ );
$seen{$first_bit} = $element;
}
foreach my $first_bit ( keys %seen ) {
print $seen{$first_bit}, "\n";
}
我们迭代数组,从字符串中选择“第一位”(我在这个例子中抓住'on'前面的任何东西 - 你可能想要匹配不同的东西)。
通过将其用作哈希键,并重复覆盖,然后我们只打印一个元素。如果你想要第一次出现,你可以测试$seen{$first_bit}
的存在,而不是最后一次出现。您可以使用Time::Piece
来解析日期并排序,如果这对您很重要。