簡體   English   中英

如果多維數組的列的所有值都是numeric,則最快返回TRUE

[英]Fastest return TRUE if all values of a column of a multidimensional array is_numeric

是否有更快的方法來檢查php中多維數組的一列中是否存在數字(非null )(例如, number9 )?

嘗試:

下面的if statement似乎工作正常。

$arr=Array(
    [0] => Array
        (
            [date] => 2019-01-16
            [number1] => 20.4
            [number2] => 20.54
            [number3] => 19.71
            [number4] => 19.73
            [number5] => 70849266
            [number6] => 70849266
            [number7] => -0.65
            [number8] => -3.189
            [number9] => 20.0902
            [string1] => Jan 16
            [number10] => 0.047796070100903
        )

    .
    .
    .

    [21] => Array
        (
            [date] => 2019-01-17
            [number1 => 19.49
            [number2] => 20.51
            [number3] => 19.02
            [number4] => 20.25
            [number5] => 85018421
            [number6] => 85018421
            [number7] => 0.52
            [number8] => 2.636
            [number9] => 19.7988
            [string1] => Jan 17
            [number10] => 0.075411577270313
        )

);


function isNumeric($var){
  if (is_numeric($var)){
    return true;
  } else {
    return false;
  }
}


if((array_walk(array_column($arr, "number8"), 'isNumeric'))!=1)

使用foreach循環:

$bool = true;
foreach ($arr as $row)
{
    if (!is_numeric($row['number8']))
    {
        $bool = false;
        break;
    }
}

正如我在評論中所說:

下面的if語句似乎工作正常

但是,考慮到你提出的代碼,我懷疑:讓我們看一下。

function isNumeric($var){ ... }

if(array_walk(array_column($arr, "number8"), 'isNumberic'))!=1

第一個也是最明顯的事情是這兩個

  • isNumberic VS isNumeric ,這是一個致命的未定義的函數錯誤(拼寫/錯字)。
  • )!=1然后這超出了實際條件,或者換一種方式, if(...){ !=1 }

讓我們假設這些只是問題中的拼寫錯誤。 即使你的代碼沒有我上面提到的2個“缺陷”,你仍然會遇到這個問題, array_walk通過引用工作,只返回true(總是)。 通過引用傳遞更新“原始”變量而不返回它的副本(在array_walk的情況下)

http://php.net/manual/en/function.array-walk.php

返回值返回TRUE。

無論如何,這當然只是讓你的條件通過。 所以你應該總是測試條件的傳遞和失敗(正如我在那里放置一些“罐裝”壞數據)。 這樣我知道100%確切地知道我的代碼的行為方式。

其他人已經發布了如何糾正這一點,但不是你做錯了什么。 但為了完整起見,我還是會發一個答案。

$arr = array (
    0 => 
    array (
        'date' => '2019-01-16',
        'number1' => 20.4, 
        'number2' => 20.54,
        'number3' => 19.71,
        'number4' => 19.73,
        'number5' => 70849266,
        'number6' => 70849266,
        'number7' => -0.65,
        'number8' => -3.189,
        'number9' => 20.0902,
        'string1' => 'Jan16',
        'number10' => 0.047796070100903
    ),
    array (
        'date' => '2019-01-16',
        'number1' => 20.4, 
        'number2' => 20.54,
        'number3' => 19.71,
        'number4' => 19.73,
        'number5' => 70849266,
        'number6' => 70849266,
        'number7' => -0.65,
        'number8' => 'foo',#intentially not number
        'number9' => 20.0902,
        'string1' => 'Jan16',
        'number10' => 0.047796070100903
    ),

);

$col = array_column($arr, "number8");
$col1 = array_filter($col, 'is_numeric');

if($col != $col1){
    echo "not the same\n";
}

輸出:

not the same

砂箱

我應該提一下,沒有“需要”來計算這些,因為PHP可以比較復雜對象的相等性。 因為我們在(可能)刪除一些元素之后比較相同的“根”數組(本例中$col ),如果沒有刪除任何元素,那么兩個數組不僅應該是相同的長度而且應該是“相同的”。

此外,如果你想在一行(在條件內)這樣做,你可以這樣做:

if( ($col = array_column($arr, "number8")) && $col != array_filter($col, 'is_numeric')){
    echo "not the same\n";
}

這有點難以閱讀,並注意$col = array_column賦值。

這是我的想法。
首先是只過濾數組中的數值,並與原始數據進行比較:

function with_array_filter($arr) {
    return $arr == array_filter($arr, 'is_numeric');
}

第二個例子使用了一個浮動然后回到字符串,請記住,這對於非常大的數字來說不是准確的,但是似乎是最快的(如果你完全關心它):

function is_numeric_array_with_cast($arr) {
    foreach ($arr as $b) {
        if ($b != (string)(float)$b) {
            return false;
        }
    }
    return true;
}

然而,最簡單的解決方案可能只是在函數內部foreach處理數組並提前返回:

function is_numeric_array_with_func($arr) {
    foreach ($arr as $b) {
        if (!is_numeric($b)) {
            return false;
        }
    }
    return true;
}

在PHP 7.2上以超過100000次迭代的20個元素為基准進行基准測試:

$falseArray = [
    '1',
    2.5,
    -10,
    32,
    11.0,
    2.5,
    100101221,
    345,
    -10,
    '-10',
    '+10',
    '10',
    12,
    PHP_INT_MAX,
    PHP_INT_MAX + 1.4e5,
    '-10',
    null,
    'a',
    '5',
    5
];

Matt Fryer
Time: 4.8473789691925

is_numeric_array_with_func
Time:  4.0416791439056

is_numeric_array_with_cast
Time:  3.2953300476074

with_array_filter
Time:  3.99729180336

萬分感謝所有人,感謝您的精彩回答!

在我的電腦上,我嘗試了PHP 5.5.38中的四個函數,迭代次數約為5000次,總時間為:

"is_numeric_array_with_cast total time is 0.44153618812561"
"with_array_filter total time is 0.21628260612488"
"is_numeric_array_with_func total time is 0.14269280433655"
"is_numeric_matt_fryer total time is 0.155033826828"


$t1=$t2=$t3=$t4=0;
foreach($arrs as $k=>$arr){
    $s1=microtime(true);
    is_numeric_array_with_cast(array_column($arr, "number8"));
    $e1=microtime(true)-$s1;
    $t1=$t1+$e1;

    $s2=microtime(true);
    with_array_filter(array_column($arr, "number8"));
    $e2=microtime(true)-$s2;
    $t2=$t2+$e2;


    $s3=microtime(true);
    is_numeric_array_with_func(array_column($arr, "number8"));
    $e3=microtime(true)-$s3;
    $t3=$t3+$e3;

    $s4=microtime(true);
    is_numeric_matt_fryer(array_column($arr, "number8"),"number8");
    $e4=microtime(true)-$s4;
    $t4=$t4+$e4;

}






function is_numeric_array_with_cast($arr) {
    foreach ($arr as $b) {
        if ($b != (string)(float)$b) {
            return false;
        }
    }
    return true;
}


function with_array_filter($arr) {
    return $arr == array_filter($arr, 'is_numeric');
}


function is_numeric_array_with_func($arr) {
    foreach ($arr as $b) {
        if (!is_numeric($b)) {
            return false;
        }
    }
    return true;
}

function is_numeric_matt_fryer($arr,$str){
  $bool = true;
  foreach ($arr as $row)
  {
      if (!is_numeric($row[$str]))
      {
          $bool = false;
      }
  }
  return $bool;
}

array_walk只是將函數應用於每個元素,它不會告訴您它是否成功。 array_filter將執行您正在尋找的內容,因為它會刪除與過濾器函數不匹配的任何元素。

$result = array_filter(array_column($arr, "number8"), 'is_numeric');
if (count($result) === count($arr)) {
    // all numeric
} else {
    // one or more not numeric
}

注意,這里可以直接使用is_numeric ,因為回調只接受一個參數,即數組元素的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM