删除阵列元素

问题描述 投票:0回答:4

goal:从阵列中删除特定的value 我写了一个脚本,它的工作正常,但是我不高兴的写作方式。因此,我很想知道有一种更好的写作方法。请考虑以下用例:

我有一个嵌套的哈希/哈希/数组...如下所示。我需要删除任何具有其名称的数组值:

local

因此,脚本删除了“

#!/usr/bin/perl -w use strict; use Data::Dumper; my $hash = { esx1 => { cluster => "clu1", fd => "fd1", ds => [ 'ds1', 'ds2', 'localds', ], }, esx2 => { cluster => "clu2", fd => "fd2", ds => [ 'ds3', 'ds4', 'dslocal', ], }, }; foreach my $a ( keys %$hash ) { foreach ( 0..$#{ $hash->{$a}->{ds} } ) { delete $hash->{$a}->{ds}->[$_] if $hash->{$a}->{ds}->[$_] =~ /local/i; @{ $hash->{$a}->{ds} } = grep defined, @{ $hash->{$a}->{ds} }; } } print Dumper ($hash);
”和“
localds

”,并使其他所有内容保持完整。

有一种更清洁的方式来编写
dslocal
循环?

  1. 如果我不编写上面的
    foreach ( 0..$#{$hash->{$a}->{ds} } )
    线,则结果数组的值包含
  2. grep
  3. 删除,但被
    local
    替换为
    undef
    。为什么这会发生?
        
perl
4个回答
5
投票
用于哈希中的元素。它恰好是通过实施怪异在数组上工作的,但不应依靠它。

对于数组,您要使用剪接。

splice @{ $ref->{to}->{array} }, $index, 1, ();
this thim替换为1元素的sublist,从

$index

开始,用空列表开始。

为什么首先通过数组迭代并删除元素,然后查找“未删除”节点(旁注 - 此

()

应该在室外循环)?您可以从一开始就可以寻找好的节点!用以下方式替换整个循环

grep
    


2
投票

不多,而是:

for my $h (values %$hash){
    $h->{ds} = [ grep { $_ !~ /local/i } @{$h->{ds}} ];
}
delete不会改变数组结构,而只是改变数组内容。由于您的方法,您需要抓取定义的条目以创建所需结构的新数组,然后覆盖旧数组。

1
投票
perldoc页面上更好地解释。
  
delete()也可以在数组和阵列切片上使用,但其行为不那么简单。尽管存在()将返回已删除条目的false,但删除数组元素永远不会更改现有值的索引;为此使用shift()或剪接()。但是,如果所有已删除的元素都落在数组的末尾,则数组的大小会缩小到最高元素的位置,该位置仍然测试了已存在的最高元素,或者如果没有测试,则缩小到0。

1
投票
Edit:

被暴民剪接指出的是您想要的事情:
foreach my $a ( keys %$hash )
{
    my $temp;
    foreach ( @{ $hash->{$a}->{ds} } ) 
    {   
        push(@$temp, $_) unless $_ =~ /local/i;
    }
    $hash->{$a}->{ds} = $temp;
}

您可以使用list :: moreutils qw/ first_idx/获取/ local/ likeso的索引 foreach my $a ( keys %$hash ) { for(0..$#{ $hash->{$a}->{ds} } ) { splice( @{ $hash->{$a}->{ds} }, $_, 1 ) if $hash->{$a}->{ds}->[ $_ ] =~ /local/i; } }

然后做你想做的事。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.