Как преобразовать значения массива из строки в Int? - PullRequest
206 голосов
/ 07 марта 2012
$string = "1,2,3"
$ids = explode(',', $string);
var_dump($ids);

возвращает

array(3) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(1) "3"
}

Мне нужно, чтобы значения были типа int вместо типа string.Есть ли лучший способ сделать это, чем перебирать массив с помощью foreach и конвертировать каждую строку в int?

Ответы [ 11 ]

468 голосов
/ 07 марта 2012

Вы можете достичь этого с помощью следующего кода,

$integerIDs = array_map('intval', explode(',', $string));
37 голосов
/ 20 марта 2013

Это почти в 3 раза быстрее, чем explode(), array_map() и intval():

$integerIDs = json_decode('[' . $string . ']', true);
34 голосов
/ 02 ноября 2015

Так что мне было интересно узнать о производительности некоторых методов, упомянутых в ответах для большого числа целых чисел.

Подготовка

Просто создаю массив из 1 миллиона случайных целых чисел от 0 до 100. Затем я сжал их, чтобы получить строку.

  $integers = array();

  for ($i = 0; $i < 1000000; $i++) {
      $integers[] = rand(0, 100);
  }

  $long_string = implode(',', $integers);

Метод 1

Это один из ответов Марка:

$integerIDs = array_map('intval', explode(',', $long_string));

Метод 2

Это подход JSON:

  $integerIDs = json_decode('[' . $long_string . ']', true);

Метод 3

Я придумал это как модификацию ответа Марка. Это все еще использует функцию explode(), но вместо вызова array_map() я использую обычный цикл foreach, чтобы выполнить работу, чтобы избежать накладных расходов, которые может иметь array_map(). Я также анализирую с (int) против intval(), но я пробовал оба, и с точки зрения производительности нет большой разницы.

  $result_array = array();
  $strings_array = explode(',', $long_string);

  foreach ($strings_array as $each_number) {
      $result_array[] = (int) $each_number;
  }

Результаты:

Method 1        Method 2        Method 3
0.4804770947    0.3608930111    0.3387751579
0.4748001099    0.363986969     0.3762528896
0.4625790119    0.3645150661    0.3335959911
0.5065748692    0.3570590019    0.3365750313
0.4803431034    0.4135499001    0.3330330849
0.4510772228    0.4421861172    0.341176033
0.503674984     0.3612480164    0.3561749458
0.5598649979    0.352314949     0.3766179085
0.4573421478    0.3527538776    0.3473439217

0.4863037268    0.3742785454    0.3488383293

Суть в среднем. Похоже, что первый метод был немного медленнее для 1 миллиона целых чисел, но я не заметил трехкратного увеличения производительности метода 2, как указано в ответе. Оказалось, цикл foreach был самым быстрым в моем случае. Я сделал бенчмаркинг с Xdebug.

Редактировать: Прошло много времени с тех пор, как ответ был первоначально опубликован. Чтобы уточнить, тест был сделан в php 5.6.

16 голосов
/ 09 мая 2016

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

// if you have your values in the format '1,2,3,4', use this before:
// $stringArray = explode(',', '1,2,3,4');

$stringArray = ['1', '2', '3', '4'];

$intArray = array_map(
    function($value) { return (int)$value; },
    $stringArray
);

var_dump($intArray);

Вывод будет:

array(4) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
}
11 голосов
/ 10 октября 2013

В решении Марка вы вернете array([0]=> int 0), если попытаетесь разобрать строку, например "test".

$integerIDs = array_map( 'intval', array_filter( explode(',', $string), 'is_numeric' ) );
7 голосов
/ 15 июня 2016

Не уверен, что это быстрее, но переворачивание массива дважды приведёт числовые строки к целым числам:

$string = "1,2,3, bla";
$ids = array_flip(array_flip(explode(',', $string)));
var_dump($ids);
5 голосов
/ 30 ноября 2017

Альтернативный более короткий метод может быть:

$r = explode(',', $s);
foreach ($r as &$i) $i = (int) $i;

Он имеет те же характеристики, что и метод 3.

5 голосов
/ 09 марта 2016

Если у вас есть массив, подобный:

$runners = ["1","2","3","4"];

И если вы хотите преобразовать их в целые числа и не выходить за пределы массива, выполните следующее:

$newArray = array_map( create_function('$value', 'return (int)$value;'),
            $runners);
3 голосов
/ 24 января 2016

Не усложняйте ...

$intArray = array ();
$strArray = explode(',', $string);
foreach ($strArray as $value)
$intArray [] = intval ($value);

Почему вы ищете другие пути?Цикл делает работу без боли.Если производительность вас беспокоит, вы можете перейти с json_decode ().Люди писали, как это использовать, поэтому я не включаю его здесь.

Примечание: При использовании оператора == вместо === ваши строковые значения автоматически преобразуются в числа (например, целое или двойное), если они образуют действительное число без кавычек.Например:

$str = '1';
($str == 1) // true but
($str === 1) //false

Таким образом, == может решить вашу проблему, эффективно, но сломается, если вы будете использовать === в сравнениях.

2 голосов
/ 11 апреля 2017

Если у вас есть многомерный массив, ни одно из ранее упомянутых решений не будет работать. Вот мое решение:

public function arrayValuesToInt(&$array){
  if(is_array($array)){
    foreach($array as &$arrayPiece){
      arrayValuesToInt($arrayPiece);
    }
  }else{
    $array = intval($array);
  }
}

Тогда просто сделайте это:

arrayValuesToInt($multiDimentionalArray);

Это сделает массив следующим образом:

[["1","2"]["3","4"]]

выглядит так:

[[1,2][3,4]

(Это будет работать с любым уровнем глубины)

...