is_numeric_array () отсутствует

Я обнаружил, что в PHP (или я, вероятно, не могу его найти) отсутствует функция is_numeric_array($array). Поэтому я создал его. Проблема в том, что я не думаю, что это здорово, и я не знаю, как его улучшить.

Любое предложение?

Моя первая функция

function is_numeric_array($array)
{
    $i = 0;
    foreach ($array as $a => $b) { if (is_int($a)) { ++$i; } }
    if (count($array) === $i) { return true; }
    else { return false; }
}

is_numeric_array(array(0,0,0,0,0)); // true
is_numeric_array(array('str' => 1, 'str2' => 2, 'str3' => 3)); // false

Пример

Как я уже сказал, я приведу пример того, как это может быть полезно.

function is_numeric_array($array)
{
    # Code below
}

function someFunction($array)
{
    if (is_numeric_array($array))
    {
        $query = $array[0];
        $param = $array[1];
        $fetch = $array[2];
    }
    else
    {
        $query = $array['query'];
        $param = $array['param'];
        $fetch = $array['fetch'];
    }

    # Do your sql/pdo stuff here
}

# This use is the same of ...
someFunction(array(
    'PDO SQL STATEMENT', 
    array('param1' => 1, 'param2' => 2, 'param3' => 3),
    true
));

# ... this one.
someFunction(array(
    'query' => 'PDO SQL STATEMENT',
    'param' => array('param1' => 1, 'param2' => 2, 'param3' => 3),
    'fetch' => true
));

# To choose one form instead of the other is coder's decision
# Also I know it is useless but I was just wondering why anybody actually looked forward this function
32 голоса | спросил Shoe 25 Jpm1000000pmTue, 25 Jan 2011 19:13:34 +030011 2011, 19:13:34

8 ответов


45

Вместо использования счетчика для подсчета ключей, для которых условие истинно, вы можете просто вернуть значение false, как только найдете ключ, который не является int и возвращает true, если цикл достигнет своего конца, не найдя такой ключ

foreach ($array as $a => $b) {
    if (!is_int($a)) {
        return false;
    }
}
return true;

Это имеет то преимущество, что он короткозамкнутый (то есть он останавливает итерацию после того, как находит ключ, который не является int) и избавляется от счетчика.

ответил sepp2k 25 Jpm1000000pmTue, 25 Jan 2011 19:58:01 +030011 2011, 19:58:01
14

Улучшение немного на @ sepp2k answer (+1) (удаление «предупреждения неиспользуемой переменной» некоторые инструменты выплюнут):

foreach (array_keys($array) as $a)) {
    if (!is_int($a)) {
        return false;
    }
}
return true;

Если вы хотите проверить, является ли это линейным массивом:

return array_merge($array) === $array;

или решение RobertPitt :) (Также +1 там)

Но мое главное:

Зачем вам это нужно, я никогда не использовал для чего-то вроде этого, и мог быть в том, что решение - это изменение и недостаток дизайна API или дефект структуры данных где-то? Не слишком, но может.

Ответ на комментарий OP:

Я создаю метод db для запросов, которые необходимы для массива из 3 ключей. В случае, если массив является числовым, порядок должен быть: оператор, параметры, выборка. Если это не так, то кодер указывает строку ключа, порядок может быть разным, и два из трех необходимых параметров могут быть пустыми.

Хорошо, тогда попробую сделать это, чтобы указать ваши требования:)

my_db_function(
    array("myquery", array("params", "..."), "myfetchmode")
);
// or 
my_db_function(
    array("params" => "myquery", "fetchmode" => "myfetchmode, "params" => array("myparams", "...) )
); 

Возможно, я немного понял немного, но он должен понять, как можно построить это с другой проверкой:)

function my_db_fuction($statement) {

    if(isset($statement["query"])) { // Assoc 'Mode'
        $query = $statement["query"];
        if(isset($statement["params"])) { $params = $statement["params"]; } 
        else { $params = array(); }
        if(isset($statement["fetchmode"])) { $fetchmode = $statement["fetchmode"]; }
        else { $fetchmode = "select"; // optional param, default value here

    } else if(isset($statement[0]) { // Linear Array Mode

        $query = $statement[0];
        if(isset($statement[1])) { $params = $statement[1]; } 
        else { $params = array(); }
        if(isset($statement[2])) { $fetchmode = $statement[2]; }
        else { $fetchmode = "select"; // optional param, default value here

    } else {
         // Error, misformed format
    }
    // Now we got our 3 variables :)
}

Это все еще довольно большой блок кода, но я не хотел его сокращать и рисковать еще хуже.

Что бы я сделал с этим, создайте my_db_stuff_param_helper ($ aParams), который всегда будет возвращать массив, содержащий 3 ключа, заполненные реальными значениями (или значения по умолчанию, если ничего не было передано)

  function my_db_fuction($statement) {
      $statement = my_db_parse_params($statement);
      // now e.g. $statement["query"] will always be there
  }

что-то по этим линиям «чувствует» (субъективное, я знаю) лучше, чем создание общей функции для проверки ключа. (Я думаю, что это isset ($ statement ["query"]) вместо is_numeric_array , к которому я сворачиваю :):

ответил edorian 25 Jpm1000000pmTue, 25 Jan 2011 21:24:34 +030011 2011, 21:24:34
6

Сначала я не понимал, что вы хотите проверить, являются ли ключи целыми числами. Если причина, по которой вы это делаете, состоит в том, чтобы убедиться, что ключи 0,1,2,3,4 .. и т. Д. Как индексированный массив, а не ассоциативный массив, вы можете использовать это:

function is_numeric_array($arr)
{
    return array_keys($arr) === range(0,(count($arr)-1));
}

/*
    * Tests
*/
var_dump(is_numeric_array(array('a', 'b', 'c'))); // true
var_dump(is_numeric_array(array("0" => 'a', "1" => 'b', "2" => 'c'))); // true
var_dump(is_numeric_array(array("1" => 'a', "0" => 'b', "2" => 'c'))); // false
var_dump(is_numeric_array(array("a" => 'a', "b" => 'b', "c" => 'c'))); // false

Результаты тестов по запросу:

Вот код, используемый для проверки выполнения:

$array = array();
for($i=0;$i<=500000;$i++)
{
    $array[] = "some_string";
}

$m_initial = memory_get_usage();
is_numeric_array($array);
$increase = memory_get_usage() - $m_initial;

Как вы можете видеть из вышеизложенного, я тестировал линейный массив с 500K строками:

Значение $increase показало 65032 (которое находится в байтах). Если мы перейдем к K B , это будет округлено до 64. Результат в KB показывает 63.507 , что, на мой взгляд, в порядке.

ответил RobertPitt 25 Jpm1000000pmTue, 25 Jan 2011 21:07:26 +030011 2011, 21:07:26
5

Хорошо, сделайте снимок для согласованности и правильных соглашений об именах (так как numeric и int означают разные вещи вместе, есть небольшая точка, вызывающая одну другую ...)

function isNumericArray(array $array) {
    foreach ($array as $a => $b) {
        if (!is_numeric($a)) {
            return false;
        }
    }
    return true;
}

function isIntArray(array $array) {
    foreach ($array as $a => $b) {
        if (!is_int($a)) {
            return false;
        }
    }
    return true;
}

Теперь, для более OO-подхода, я бы построил фильтр-фильтр:

class NumericFilterIterator extends FilterIterator {
    public function accept() {
        return is_numeric(parent::current());
    }
}

class IntFilterIterator extends FilterIterator {
    public function accept() {
        return is_int(parent::current());
    }
}

Затем, если вы просто хотите перебрать целое число, просто выполните $it = new IntFilterIterator(new ArrayIterator($array));. Если вы хотите проверить, вы можете сделать:

$it = new IntFilterIterator(new ArrayIterator($array));
if ($array != iterator_to_array($it)) {
    //Has a non-int element
}
ответил ircmaxell 25 Jpm1000000pmTue, 25 Jan 2011 23:31:58 +030011 2011, 23:31:58
5

Это будет выпадать, как только будет найден элемент, который не является int, что делает функцию более эффективной для больших массивов.

function is_numeric_array($array) {
   foreach ($array as $a=>$b) {
      if (!is_int($a)) {
         return false;
      }
   }
   return true;
}
ответил Michael K 25 Jpm1000000pmTue, 25 Jan 2011 19:28:16 +030011 2011, 19:28:16
3

Это, вероятно, будет более эффективным:

function is_numeric_array($array)
{
    $array = array_keys($array);

    if ($array === array_filter($array, 'is_int'))
    {
        return true;
    }

    return false;
}

Я только заметил, что вы действительно пытаетесь сделать, это не проверять, являются ли все ключи массива целыми, а скорее, если массив проиндексирован (неассоциативный), для этого используйте array_values() делает трюк:

function is_numeric_array($array)
{
    return ($array === array_values($array));
}
ответил Alix Axel 25 FebruaryEurope/MoscowbFri, 25 Feb 2011 14:31:13 +0300000000pmFri, 25 Feb 2011 14:31:13 +030011 2011, 14:31:13
2

Если вы на самом деле пытаетесь определить, является ли это последовательным целочисленным массивом, а не ассоциативным, то есть что-то, что json_encode сделает массив против объекта, это, вероятно, самый быстрый способ сделать это:

function is_normal_array($arr) {
    $c = count($arr);
    for ($i = 0; $i < $c; $i++) {
        if (!isset($arr[$i])) {
            return false;
        }
    }
    return true;
}

... Конечно, самый быстрый код - это код, который вы никогда не запускаете, поэтому подумайте, действительно ли вам действительно нужно это делать, и используйте его только там, где вы делаете.

ответил Jay Paroline 27 Jam1000000amThu, 27 Jan 2011 10:21:27 +030011 2011, 10:21:27
2

Это старый пост, но если вы ищете более короткое, но все же элегантное решение, используйте это:

return array_values($array) === $array

Вы даже можете использовать его как условие, так как оно довольно короткое. Приветствия

ответил humdash 21 Maypm17 2017, 17:56:13

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132