13

このPythonスニペットをPerlで表現する方法を探しています。

data = {"A": None, "B": "yes", "C": None}
key_list = [k for k in data if data[k]]  
# in this case the same as filter(lambda k: data[k], data) but let's ignore that

したがって、一方向で見ると、値がNoneまたはundefであるキーが必要です。別の見方をすれば、私が欲しいのは、条件付きのリスト内包に相当する簡潔なperlです。

4

3 に答える 3

21

私はあなたが欲しいと思いますgrep

#!/usr/bin/env perl
use strict;
use warnings;

my %data = ( A => undef, B => 'yes', C => undef );

my @keys = grep { defined $data{$_} } keys %data;

print "Key: $_\n" for @keys;

また、入力が遅すぎるので、回答を投稿する前にページをリロードする必要があると思います。ちなみに、0またはの値はnullundef値を処理するための良い方法ですが、どちらを使用しているかを覚えておいてください。偽の値と未定義の値は、Perlでは同じものではありません。明確にするために:ブールテストではfalseを返しますが、そうします。が有効な値である場合、単に真実ではなく、定義性を明示的にテストする必要があります。(ジェームズが行ったので、私は反対に行ったので、私はそれについて言及します、そしてあなたはそれが重要であるかどうかを知っているかもしれないし、知らないかもしれません。)undef000

于 2009-07-10T23:46:05.037 に答える
13

grepを使用する:

#!/usr/bin/perl

use strict;
use warnings;

my %data = ("A" => 0, "B" => "yes", "C" => 0 );
my @keys = grep { $data{$_} } keys %data;

Grepは、中括弧内の式が真の値と評価される右側のリストから値を返します。テレマコスが指摘しているように、Perlの真/偽の値を確実に理解する必要があります。この質問には、Perlの真実の概要がわかります。

リストの各要素に中かっこで囲まれた式を適用して結果を返すマップを確認することをお勧めします。例は次のとおりです。

my @data = ("A" => 0, "B" => 1, "C" => 0 );
my @modified_data = map { $data{$_} + 1 } @data;
print join ' ', @data, "\n";
print join ' ', @modified_data, "\n";
于 2009-07-10T23:42:52.097 に答える
6

テーマのバリエーションについては、autoboxをご覧ください( autobox::CoreMoose::Autoboxの実装を参照してください ) 。

use autobox::Core;

my %data = ( A => undef, B => 'yes', C => undef );
my $key_list = %data->keys->grep( sub { defined $data{$_} } );

say "Key: $_" for @$key_list;

# => Key: B


Moose :: Autoboxには、コードをDRYerにするキー/値「kv」が付属しています。

my $key_list = %data->kv->grep( sub{ defined $_->[1] } )->map( sub{ $_->[0] } );

上記のより明示的でさらに長いバージョンを次に示します。

my $key_list = %data->kv
                    ->grep( sub { my ($k, $v) = @$_; defined $v } )
                    ->map(  sub { my ($k, $v) = @$_; $k }         );
于 2009-07-11T13:03:46.453 に答える