删除 perl 数组中的 ALMOST 重复项
Remove ALMOST repeats in a perl Array
我有一个包含以下元素的数组:
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 似乎没有按预期工作,它不会转到下一条语句)。
以下将不重复的列表分配给 @filtered
:
my %seen;
my @filtered = grep { !$seen{$_}++ } @array;
你的情况需要小修整一周。引号之间的子字符串决定您是否已经看过该项目,因此需要使用它来代替 $_
.
my %seen;
my @filtered = grep { /^"([^"]+)"/ && !$seen{}++ } @array;
对于重复检测,散列是完成这项工作的工具。
#!/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";
}
我们迭代数组,从字符串中选择 'first bit'(在这个例子中我抓取 'on' 前面的任何东西——你可能想要匹配不同的东西)。
通过使用它作为哈希键,重复覆盖,然后我们只打印一个元素。如果您想要第一次出现而不是最后一次出现,您可以测试 $seen{$first_bit}
是否存在。如果这对您很重要,您可以使用 Time::Piece
来解析日期和排序。
我有一个包含以下元素的数组:
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 似乎没有按预期工作,它不会转到下一条语句)。
以下将不重复的列表分配给 @filtered
:
my %seen;
my @filtered = grep { !$seen{$_}++ } @array;
你的情况需要小修整一周。引号之间的子字符串决定您是否已经看过该项目,因此需要使用它来代替 $_
.
my %seen;
my @filtered = grep { /^"([^"]+)"/ && !$seen{}++ } @array;
对于重复检测,散列是完成这项工作的工具。
#!/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";
}
我们迭代数组,从字符串中选择 'first bit'(在这个例子中我抓取 'on' 前面的任何东西——你可能想要匹配不同的东西)。
通过使用它作为哈希键,重复覆盖,然后我们只打印一个元素。如果您想要第一次出现而不是最后一次出现,您可以测试 $seen{$first_bit}
是否存在。如果这对您很重要,您可以使用 Time::Piece
来解析日期和排序。