我正試圖更好地學習Perl的grep。
我想grep一個哈希的哪些鍵是不在一個陣列中的
my %args = ( fake => 1) 。
my @defined_args = ('color', 'color', 'data'/span>, 'figheight'/span>, 'figwidth'/span>, 'filename', 'flip', 'grid', 'labelsize', 'logscale', 'minor_gridlines')。)
my @bad_args = grep { not grep {$_} @defined_args} keys %args;
其中壞的args串列在@bad_args最后一行顯然是錯誤的。
我知道我可以用哈希值做同樣的事情,但是我希望能夠用多階grep來做這件事,即grep上的grep。
我怎樣才能像下面這樣做呢?
my @bad_args = grep { not grep{$_ eq$_} @defined_args} keys %args;
我很困惑,因為會有兩個$_,我不能對其進行平等測驗。
uj5u.com熱心網友回復:
首先是直接的回答 -- grep的那個塊,你可以把任何代碼放在里面。這就是這個塊的意義,一個元素通過/不通過的依據是最后回傳的陳述句的真實性。
my @bad_args = grep {
my $key = $_;
@defined_args == grep { $key ne $_ } @defined_args
} keys %args;
這里我們測驗一個鍵是否與陣列元素不相等,然后測驗它是否與所有的元素不相等,什么決定什么。 另一種方法是測驗它是否與任何一個元素相等,
not grep { $key eq $_ } @defined_args;
這一切都有點復雜,需要與否定詞一起作業。
但是這些都是常見的事情,而且有一些庫。
為了直接改進上述內容,
use List::Util 1. 33 qw(none); # 1.33之前是在List::MoreUtils。
my @bad_args = grep {
my $key = $_;
none { $key eq $_ } @defined_args
} keys %args;
現在,所需的 "負數 "被吸收在庫的函式名稱中,使之更容易看清。 另外,none一旦看到失敗就會停止,而grep總是處理所有的元素,所以這也更有效率。
與基于哈希的方法相比,這些方法的效率并不高(復雜度O(NM-M2/2)左右),但這對于小陣列來說是完全不重要的。 問題中提到的使用哈希值來處理與存在有關的問題是一種標準;例如,請參見這篇文章,或者下面討論的所有庫中使用的方法的來源(最簡單的例子)。
最后,雖然這個問題是關于(雙重)過濾的,但應該提到的是,我們正在尋找一個串列中的哪些元素不在另一個串列中;一個串列之間的 "差異"。 那么其他型別的庫就開始發揮作用了。一些例子
useSet::Scalar;
...
my $keys = Set::Scalar->new(keys %args)。
my $good = Set::Scalar->new(@defined_args)。
my $keys_not_in_good = $keys->difference($good);
say $keys_not_in_good;
還請注意Set::Object在同一陣營。
然后還有一些專門用于陣列比較的工具,比如List::Compare
use List::Compare;
...
my $lc = List::Compare->new('-u', '-a', @defined_args, [keys%args]) 。
my @only_in_second = $lc->get_complement() 。
say "@only_in_second"/span>。
選項-u和-a展示了模塊的一些功能,以加快事情的進展;它們并不是必須的。 這個模塊有很多東西,請看檔案。
另一端是簡單的Array::Utils。
外面還有更多。例如,請參見本頁面,以獲得大量的想法。
uj5u.com熱心網友回復:
當你陷入這種糾結時,有時最好能找到一種不同的方法。
有兩件事需要考慮。如果你想嵌套使用$_,你需要以某種方式保護外部的。由于你想在同一個運算式中使用外層和內層的,其中一個需要一個不同的名字:
在這個運算式中,你需要一個不同的名字。
grep {
my $top = $_;
my $count = grep { $top eq $_ }。...;
...
} keys %args;
但是,這個內部grep有點奇怪。你想檢查某個東西是否在一個串列中(或不在)。這就是哈希和exists的作業:
my %allowed_args = map { $_, 1 } @allowed_args;
my @found_bad_args = grep { ! exists $allowed_args{$_} } keys %args;
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/311317.html
標籤:
上一篇:連接到Websocket代理時在谷歌瀏覽器上出現錯誤
下一篇:0加一個指標是什么意思?
