Как преобразовать значения массива из строки в int?

$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 вместо строки типа. Есть ли лучший способ сделать это, чем цикл через массив с foreach и преобразование каждой строки в int?

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

подготовка

Просто создаю массив из 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) vs 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.

Ответ 4

Используйте этот код с закрытием (введенный в 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)
}

Ответ 5

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

$integerIDs = array_map( 'intval', array_filter( explode(',', $string), 'is_numeric' ) );

Ответ 6

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

$string = "1,2,3, bla";
$ids = array_flip(array_flip(explode(',', $string)));
var_dump($ids);

Ответ 7

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

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

Он имеет ту же производительность, что и метод 3.

Ответ 8

Если у вас есть массив вроде:

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

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

$newArray = array_map( create_function('$value', 'return (int)$value;'),
            $runners);

Ответ 9

Держите его простым...

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

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

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

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

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

Ответ 10

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

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]

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

Ответ 11

Мое решение - приведение каждого значения с помощью функции обратного вызова:

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

Ответ 12

Вы можете конвертировать значения в массиве:

<?php

$ids = explode(',', $strings);
foreach ($ids as $index => $value) {
    $ids[$index] = (int)$value;
}

Вы также можете вернуть возвращаемое значение функции explode в $strings и выполнить итерацию вместо использования другой переменной ($ ids).

Я думаю, что это решение - самый безопасный способ с лучшей производительностью.