删除perl数组中的ALMOST重复

时间:2015-02-09 20:05:53

标签: arrays perl

我有一个包含以下元素的数组:

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似乎没有按预期工作,它不会进入下一个语句。)

2 个答案:

答案 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来解析日期并排序,如果这对您很重要。