如何从Perl中的数组中删除元素?

时间:2015-07-21 13:30:20

标签: perl

我正在使用Config::Simple

执行配置文件

配置文件,即new.conf

[Dialer External]
pass=pass2
user=user2

[Dialer Onboard]
pass=pass1
user=user1

[Dialer Onboard1]
pass=pass1
user=user1

[Dialer Onboard2]
pass=pass1
user=user1

我正在阅读配置文件,这是我的代码

#!/usr/bin/perl
use Config::Simple;
use Data::Dumper;

$cfg = new Config::Simple(syntax => 'ini');
$cfg->read('new.conf');
$cfg = Config::Simple->import_from('new.conf', \%Config);
my @arr = ( keys %Config );
print "@arr";

哈希引用,即%Config我分配给数组@arr,输出将是

Dialer Onboard1.pass 
Dialer Onboard.pass 
Dialer Onboard.user 
Dialer Onboard2.pass 
Dialer Onboard2.user 
Dialer External.user 
Dialer External.pass 
Dialer Onboard1.user

直到这里是对的。现在我想删除一些元素并将其分配给应该是这样的新数组

Dialer Onboard1
Dialer Onboard 
Dialer Onboard 
Dialer Onboard2 
Dialer Onboard2 
Dialer External 
Dialer External 
Dialer Onboard1

以便在点(.)之后我不想要任何数据。为此,我尝试使用grep函数。这是我的代码

@arr = grep { !/./ } @arr;
my @result;
for (@arr) {
    if (/./) {
        push @result, $_;
    } 
}

但这不适合我,也可能是错误的做法。我无法确定我哪里出错了。 最后我想删除那里的重复键,这给了我这样的输出。

Dialer External 
Dialer Onboard 
Dialer Onboard1 
Dialer Onboard2

请有人帮助我并建议我如何实现这一目标。谢谢。

2 个答案:

答案 0 :(得分:6)

grep用于过滤,而不是用于更改数据。要删除点后的所有内容,请使用替换:

s/\..*// for @arr;

如果您想要唯一元素,请使用哈希:

my %uniq;
@uniq{@arr} = ();
@arr = keys %uniq;

或者,使用List::MoreUtils中的uniq

use List::MoreUtils qw{ uniq };
@arr = uniq(@arr);

答案 1 :(得分:0)

您有一个可以满足您需求的修复程序。但我有点意外,没有人注意到你真正想做的事情。

您获得比您想要的更复杂的键(和更多键)的原因是因为您使用通用配置解析器以解析器不适合的格式读取配置文件。 Config :: Simple假设一个非常平坦的键/值结构,而你真正想要的INI风格的配置更自然地表示为两级哈希。

因此,如果您使用真正的INI解析器(例如Config::INI),您的生活会立即变得更加轻松。

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use Config::INI::Reader;

my $cfg = Config::INI::Reader->read_file('new.conf');
my @arr = ( keys %$cfg );

say for @arr;

Config :: INI为您提供两级哈希,其中顶级键是块的名称。这就是你要找的东西。因此,只需在该哈希上调用keys即可获得所需内容。

使用正确的工具通常可以简化事情。