洗掉多維陣列中的陣列后,我們如何擁有普通陣列?
@p=();
my @l=([9,7],[3,4]);
push(@p,['FOO',[@l]]);
push(@p,['BAR',[[8,0]]]);
splice(@$_,0,1) for @p;
print "\n",@$_ for @p;
ARRAY(0x5624cf01e340)
ARRAY(0x5624cf028d78)
我們如何在內部/第二個 D. 上使用 1x2 大小的簡單/普通 2D 陣列。IOW 如何將其線性化為這樣
uj5u.com熱心網友回復:
必須取消參考陣列參考的元素,并復制資料。對于單個級別:
@ary = map { ref eq "ARRAY" ? @$_ : $_ } @ary;
默認情況下,ref內置采用$_. 也可以考慮使用reftypefrom Scalar::Util。然后也is_arrayref從Ref::Util 中查看。在簡單和直接的情況下,內置函式很好。
如果有更深的級別,請在每個級別上使用上述內容。對于問題的追求,從兩級深度輸入資料中保留一層嵌套:
for my $elem (@p) {
@$elem = map { ref eq "ARRAY" ? @$_ : $_ } @$elem;
}
由于$elem別名@p此代碼的當前元素更改了陣列。
如果有更多級別(可能深度不同),則可以遞回或迭代地處理。粗略的實作:
遞回:
sub flatten_recurse {
return map { ref eq 'ARRAY' ? flatten_recurse(@$_) : $_ } @_
}
這在大型資料結構上可能很昂貴(但只有在確實如此時才擔心)。
迭代:
sub flatten_iter {
my @deque = @_;
my @flat;
while (@deque) {
my $front = shift @deque;
if (ref($front) eq 'ARRAY') {
unshift @deque, @$front;
} else {
push @flat, $front;
}
}
return \@flat;
}
在這里,您還可以以不同的組合使用pop和push。以上保持了順序,就像將復雜結構簡化為扁平結構時一樣有意義。
如果還有其他復雜性,例如其他型別的參考(它們本身包含要解包的陣列參考),則需要相應地進行調整。還需要添加檢查,特別是回圈參考。例如,請參閱此 SO 頁面和此 perlmonks 頁面。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/395616.html
上一篇:Scala中的初始陣列元素?
