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

188
$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?

Теги:
string
int
explode

11 ответов

399
Лучший ответ
$integerIDs = array_map('intval', explode(',', $string));
  • 1
    но если у вас есть строка 'test', вы получите: array ([0] => 0)
  • 7
    @Dmitry - это верно .... это ответ на вопрос ОП, а не на 100% идеальный ответ на каждый потенциальный связанный вопрос. OP содержит строку числовых значений, разделенных запятыми, а не текст и цифры
Показать ещё 4 комментария
35

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

$integerIDs = json_decode('[' . $string . ']', true);
  • 0
    не работает .. "json_decode" возвращает ноль
  • 1
    @Binod ваша строка, вероятно, синтаксическая ошибка. Он должен быть отформатирован так: $ string = "1,2,3";
Показать ещё 10 комментариев
29

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

Подготовка

Просто создав массив из 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 миллиона целых чисел, но я не заметил 3-кратное увеличение производительности метода 2, как указано в ответе. Оказалось, что цикл foreach был самым быстрым в моем случае. Я сделал бенчмаркинг с Xdebug.

  • 0
    Я действительно задаюсь вопросом, осталась ли производительность в PHP 7 такой же, и еще более любопытно, как бы это сделал Метод 1 array_map в сочетании с приведением метода 3 к закрытию / анонимному обратному вызову ...
  • 0
    array_map(function($v){ return (int)$v; }, $strings_array); это то, что я имел ввиду
16

Используйте этот код с закрытием (введенный в 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)
}
  • 1
    Согласно документу , это также быстрее, чем create_function, предложенный в других ответах.
  • 1
    @ пока Да, вы правы. И create_function устарела, начиная с PHP 7.2.0.
9

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

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

5

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

$string = "1,2,3, bla";
$ids = array_flip(array_flip(explode(',', $string)));
var_dump($ids);
  • 0
    TIL отличный трюк!
5

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

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

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

$newArray = array_map( create_function('$value', 'return (int)$value;'),
            $runners);
  • 0
    Работает ли это для многомерного массива?
  • 0
    create_function устарела с версии PHP 7.2.0. Лучше проверьте мой ответ без create_function, но с анонимной функцией.
4

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

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

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

  • 0
    самое короткое, но гибкое решение для меня.
2

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

$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

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

1

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

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]

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

0

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

<?php

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню