是否存在更快的方法来检查数字中是否存在数字(不是null
)
PHP中的多维数组的列(例如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)
答案 0 :(得分:1)
使用foreach
循环:
$bool = true;
foreach ($arr as $row)
{
if (!is_numeric($row['number8']))
{
$bool = false;
break;
}
}
答案 1 :(得分:1)
我在评论中说:
下面的if语句似乎可以正常工作
但是,鉴于您提出的代码,我对此表示怀疑:让我们来看一下。
function isNumeric($var){ ... }
if(array_walk(array_column($arr, "number8"), 'isNumberic'))!=1
最明显的第一件事就是这些2
isNumberic
与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
的分配。
答案 2 :(得分:1)
这是我的主意。
首先是只过滤数组中仅包含数字的值,然后将其与原始值进行比较:
function with_array_filter($arr) {
return $arr == array_filter($arr, 'is_numeric');
}
第二个示例使用强制转换为浮点数然后返回字符串的方式,请记住,这对于很大的数字来说并不准确,但是似乎是最快的(如果您对此很在意): / p>
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上通过20万个元素的数组进行了100000次迭代:
$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
答案 3 :(得分:1)
感谢每一个人,为您提供出色的答案!
在我的PC上,我用PHP 5.5.38尝试了约4000次迭代的四个函数,总时间为:
"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;
}
答案 4 :(得分:0)
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
,因为回调只接受一个参数,即数组元素的值。