[英]Count "truthy" values in a 2d array
給定以下數組$mm
Array
(
[147] => Array
(
[pts_m] =>
[pts_mreg] => 1
[pts_cg] => 1
)
[158] => Array
(
[pts_m] =>
[pts_mreg] =>
[pts_cg] => 0
)
[159] => Array
(
[pts_m] =>
[pts_mreg] => 1
[pts_cg] => 1
)
)
當我運行count(array_filter($mm))
時,我得到3
作為結果,因為它不是遞歸的。
count(array_filter($mm), COUNT_RECURSIVE)
也不會這樣做,因為我實際上需要遞歸地運行array_filter
,然后計算它的結果。
所以我的問題是:在這種情況下如何遞歸運行array_filter($mm)
? 我在這里的預期結果是4
。
請注意,我沒有使用任何回調,因此我可以排除錯誤、null 和空。
//This function filters an array and remove all null values recursively.
<?php
function array_filter_recursive($input)
{
foreach ($input as &$value)
{
if (is_array($value))
{
$value = array_filter_recursive($value);
}
}
return array_filter($input);
}
?>
//Or with callback parameter (not tested) :
<?php
function array_filter_recursive($input, $callback = null)
{
foreach ($input as &$value)
{
if (is_array($value))
{
$value = array_filter_recursive($value, $callback);
}
}
return array_filter($input, $callback);
}
?>
應該管用
$count = array_sum(array_map(function ($item) {
return ((int) !is_null($item['pts_m'])
+ ((int) !is_null($item['pts_mreg'])
+ ((int) !is_null($item['pts_cg']);
}, $array);
或者可能
$count = array_sum(array_map(function ($item) {
return array_sum(array_map('is_int', $item));
}, $array);
肯定有更多可能的解決方案。 如果你想使用array_filter()
(沒有回調)請記住,它也將0
視為false
,因此它將從數組中刪除任何0
值。
如果您在 5.3 之前的版本中使用 PHP,我會使用foreach
-loop
$count = 0;
foreach ($array as $item) {
$count += ((int) !is_null($item['pts_m'])
+ ((int) !is_null($item['pts_mreg'])
+ ((int) !is_null($item['pts_cg']);
}
關於下面的評論:
Thx @kc 我實際上希望該方法刪除 false、0、空等
當這真的只是你想要的,解決方案也很簡單。 但是現在不知道怎么解釋
我的預期結果是 5。
無論如何,它現在很短:)
$result = array_map('array_filter', $array);
$count = array_map('count', $result);
$countSum = array_sum($count);
結果數組看起來像
Array
(
[147] => Array
(
[pts_mreg] => 1
[pts_cg] => 1
)
[158] => Array
(
)
[159] => Array
(
[pts_mreg] => 1
[pts_cg] => 1
)
)
更好的選擇
一種一直對我有用的實現是這個:
function filter_me(&$array) {
foreach ( $array as $key => $item ) {
is_array ( $item ) && $array [$key] = filter_me ( $item );
if (empty ( $array [$key] ))
unset ( $array [$key] );
}
return $array;
}
我注意到有人創建了一個類似的 function,但在我看來,這個有幾個優點:
基准
我希望它有所幫助。
這個 function 通過提供的回調有效地應用 filter_recursive
class Arr {
public static function filter_recursive($array, $callback = NULL)
{
foreach ($array as $index => $value)
{
if (is_array($value))
{
$array[$index] = Arr::filter_recursive($value, $callback);
}
else
{
$array[$index] = call_user_func($callback, $value);
}
if ( ! $array[$index])
{
unset($array[$index]);
}
}
return $array;
}
}
你會這樣使用它:
Arr::filter_recursive($my_array, $my_callback);
這可能會幫助某人
我需要一個數組過濾器遞歸 function 將遍歷所有節點(包括 arrays,以便我們有可能丟棄整個數組),所以我想出了這個:
public static function filterRecursive(array $array, callable $callback): array
{
foreach ($array as $k => $v) {
$res = call_user_func($callback, $v);
if (false === $res) {
unset($array[$k]);
} else {
if (is_array($v)) {
$array[$k] = self::filterRecursive($v, $callback);
}
}
}
return $array;
}
在此處查看更多示例: https://github.com/lingtalfi/Bat/blob/master/ArrayTool.md#filterrecursive
這應該適用於回調和模式支持以及對深度的可選支持。
function array_filter_recursive(array $array, callable $callback = null, int $mode = 0, int $depth = -1): array
{
foreach ($array as & $value) {
if ($depth != 0 && is_array($value)) {
$value = array_filter_recursive($value, $callback, $mode, $depth - 1);
}
}
if ($callback) {
return array_filter($array, $callback, $mode);
}
return array_filter($array);
}
為嵌套的 arrays 調用$depth = 0
的array_filter
,將產生與 array_filter 相同的結果。
<?php
$mm = array
(
147 => array
(
"pts_m" => "",
"pts_mreg" => 1,
"pts_cg" => 1
) ,
158 => array
(
"pts_m" => null ,
"pts_mreg" => null,
"pts_cg" => 0
),
159 => array
(
"pts_m" => "",
"pts_mreg" => 1,
"pts_cg" => 1
)
);
$count = 0;
foreach ($mm as $m) {
foreach ($m as $value) {
if($value !== false && $value !== "" && $value !== null) {
$count++;
}
}
}
echo $count;
?>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.