删除 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 来解析日期和排序。