如何从散列json数组中删除卷括号

  • 本文关键字:删除 数组 json arrays perl hash
  • 更新时间 :
  • 英文 :


我有一个哈希数组,看起来像这样:

my $names = [
{
'name' => 'John'
},
{
'name' => '$teven'
},
{
'name' => 'Edgar'
}
];

我试图验证它以删除特殊字符,空格等,但是当我删除密钥时,我留下{}。例如:

foreach (@{ $names}) {
if ($_->{name} =~ /[^w+]/ ) {
print "Deleting $_->{name} due to non-standard characters" and delete $_->{name};
}
}

然而,之后我留下了这个结果:

my $names = [
{
'name' => 'John'
},
{},
{
'name' => 'Edgar'
}
];

而不是:

my $names = [
{
'name' => 'John'
},
{
'name' => 'Edgar'
},
];

如何在删除键时删除额外的花括号?

注。为了澄清,因为我看到我的问题已被编辑,哈希数组与我之前发布的完全相同:

{
'name' => 'John'
}
{
'name' => '$teven'
}
{
'name' => 'Edgar'
}

Not with, and [];就像我之前做的decode_json一样,所以基本上只有花括号会导致问题,而不是逗号和方括号。

从散列中删除键并不会删除散列本身,即使删除后散列为空。如果要删除空散列,则必须显式地这样做。一种方法是在循环后面加上以下内容:

@{ $names } = grep { keys %{ $_ } } @{ $names };

内置的grep要么接受一个块(如上所述),要么接受一个表达式加一个列表。它只返回那些块(或表达式)为真的元素。内置的keys返回哈希的键。在标量上下文中,它返回键的数量,因此只有当哈希没有键时才为false。我相信在现代perl中,该操作在布尔上下文中进行了优化,因此不会生成整个键列表。

是的,这里假设@{ $names }的内容都是哈希引用,但是你的代码做了同样的假设。

尝试在循环内做一些事情是很诱人的,但实际上在迭代数组时删除数组元素是一个麻烦的方法。我能想到的最好的循环是$_ = undef unless keys %{ $_ };之类的东西,它用undef替换空哈希引用——可能不是您想要的。

当你想从数组中删除哈希时,你正在从哈希中删除。

当你想过滤一个数组时,grep是你的朋友。

@$names =
grep {
if ( $_->{name} =~ /W/ ) {
print "Deleting $_->{name} due to non-standard charactersn";
0
} else {
1
}
}
@$names;

grep中产生副作用有点奇怪。如果你不喜欢它,你也可以像这样使用:

my @filtered;
for ( @$names ) {
if ( $_->{name} =~ /W/ ) {
print "Deleting $_->{name} due to non-standard charactersn";
} else {
push @filtered, $_;
}
}
$names = @filtered;

你也可以使用效率较低的@$names = @filtered;,而不是$names = @filtered;,如果你有其他引用数组。

最新更新