использовать array_map для проверки значений?

StackOverflow https://stackoverflow.com/questions/1915595

  •  20-09-2019
  •  | 
  •  

Вопрос

Можно ли использовать array_map() для проверки значений массива?Я хочу убедиться, что все элементы массива являются числовыми.

Я пробовал и то, и другое

$arrays = array(
         array(0,1,2,3 )
        , array ( 0,1, "a", 5 )
);

foreach ( $arrays as $arr ) {

        if ( array_map("is_numeric", $arr) === FALSE ) {
                echo "FALSE\n";
        } else {
                echo "TRUE\n";
        }
}

и

$arrays = array(
         array(0,1,2,3 )
        , array ( 0,1, "a", 5 )
);

foreach ( $arrays as $arr ) {

        if ( ( array_map("is_numeric", $arr) ) === FALSE ) {
                echo "FALSE\n";
        } else {
                echo "TRUE\n";
        }
}

И за то, и за другое я получаю

TRUE
TRUE

Можно ли это сделать?Если да, то что я делаю не так?

Примечание:Я знаю, что могу получить желаемую функциональность из цикла foreach.

Это было полезно?

Решение

array_map возвращает массив.Поэтому это всегда будет считаться «истинным».Теперь, если вы array_search в случае ЛОЖЬ вы сможете получить желаемый эффект.

Из Страница PHP.net

array_map() returns an array containing all the elements of 
arr1 after applying the callback function to each one.

Это означает, что в настоящее время у вас есть массив, который содержит true или false для каждого элемента.Вам нужно будет использовать array_search(false,$array) чтобы узнать, есть ли ложные значения.

Другие советы

Обычно я большой сторонник array_map(), array_filter(), и т. д., но в этом случае foreach() будет лучшим выбором.Причина в том, что с array_map() и другие, он пройдет через весь массив, несмотря ни на что.Но для ваших целей вам нужно пройтись по массиву только до тех пор, пока не встретите значение, для которого is_numeric() возвращает false, и, насколько мне известно, в PHP нет способа выйти из этих методов.

Другими словами, если в вашем массиве 1000 элементов, а пятый не является числовым, используйте array_map() все равно проверит оставшиеся 995 значений, даже если вы уже знаете, что массив не прошел ваш тест.Но если вместо этого вы используете foreach() и имеете его break на is_numeric() == false, то вам нужно будет проверить только первые пять элементов.

Вы могли бы использовать filter, но в итоге получается ужасный фрагмент кода

$isAllNumeric = count(array_filter($arr, "is_numeric")) === count($arr)

Использование пользовательской функции делает его немного лучше, но все еще не идеальным

$isAllNumeric = count(array_filter($arr, function($x){return !is_numeric($x);})) === 0

Но если бы вы использовали пользовательские функции, array_reduce работал бы, но у него все еще есть некоторые недостатки.

$isAllNumeric = array_reduce($arr,
                             function($x, $y){ return $x && is_numeric($y); },
                             true);

Недостатки заключаются в том, что он не сломается, когда найдет то, что ему нужно, поэтому приведенные выше функциональные предложения не очень эффективны.Вам нужно было бы написать функцию, подобную этой:

function array_find(array $array, $callback){
    foreach ($array as $x){ //using iteration as PHP fails at recursion
        if ( call_user_func($callback, array($x)) ){
            return $x;
        }
    }
    return false;
}

И используйте это вот так

$isAllNumeric = array_find($arr, function($x){return !is_numeric($x);})) !== false;

у меня есть две крошечные, но чрезвычайно полезные функции в моей «стандартной библиотеке»

function any($ary, $func) {
   foreach($ary as $val)
      if(call_user_func($func, $val)) return true;
   return false;
}

function all($ary, $func) {
   foreach($ary as $val)
      if(!call_user_func($func, $val)) return false;
   return true;
}

в твоем примере

 foreach ( $arrays as $arr )
    echo all($arr, 'is_numeric') ? "ok" : "not ok";

ИМХО, более элегантный подход.:

foreach ($arrays as $array)
{
 if (array_product(array_map('is_numeric', $array)) == true)
 {
  echo "TRUE\n";
 }

 else
 {
  echo "FALSE\n";
 }
}

Это вернет true, если все значения являются числовыми, и false, если какое-либо из значений не является числовым.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top