$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?
$integerIDs = array_map('intval', explode(',', $string));
Это почти в 3 раза быстрее, чем array_map()
, array_map()
и intval()
:
$integerIDs = json_decode('[' . $string . ']', true);
Поэтому мне было интересно узнать о некоторых методах, упомянутых в ответах на большое количество целых чисел.
Просто создав массив из 1 миллиона случайных чисел от 0 до 100. Чем я, я их взорвал, чтобы получить строку.
$integers = array(); for ($i = 0; $i < 1000000; $i++) { $integers[] = rand(0, 100); } $long_string = implode(',', $integers);
Это один лайнер от ответа Марка:
$integerIDs = array_map('intval', explode(',', $long_string));
Это подход JSON:
$integerIDs = json_decode('[' . $long_string . ']', true);
Я придумал это как модификацию ответа Марка. Это все еще использует функцию array_map()
, но вместо вызова 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.
Используйте этот код с закрытием (введенный в 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) }
$integerIDs = array_map( 'intval', array_filter( explode(',', $string), 'is_numeric' ) );
В решении Марка вы вернете array([0]=> int 0)
если попытаетесь проанализировать строку, такую как «тест».
Если у вас есть массив вроде:
$runners = ["1","2","3","4"];
И если вы хотите скрыть их целыми числами и сохранить их в массиве, следуйте следующим инструкциям:
$newArray = array_map( create_function('$value', 'return (int)$value;'), $runners);
Не уверен, что это быстрее, но перевертывание массива в два раза приведет числовые строки к целым числам:
$string = "1,2,3, bla"; $ids = array_flip(array_flip(explode(',', $string))); var_dump($ids);
Будь проще…
$intArray = array (); $strArray = explode(',', $string); foreach ($strArray as $value) $intArray [] = intval ($value);
Почему вы ищете другие способы? Зацикливание делает работу без боли. Если производительность вас беспокоит, вы можете пойти с json_decode ()
. Люди опубликовали, как использовать это, поэтому я не включаю его здесь.
Примечание. При использовании оператора == вместо === ваши строковые значения автоматически преобразуются в числа (например, целочисленные или двойные), если они образуют допустимое число без кавычек. Например:
$str = '1'; ($str == 1) // true but ($str === 1) //false
Таким образом, == может решить вашу проблему, является эффективным, но будет разорваться, если вы используете === в сравнении.
Если у вас многомерный массив, ни одно из вышеперечисленных решений не будет работать. Вот мое решение:
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]
(Это будет работать с любым уровнем глубины)
Альтернативным более коротким способом может быть:
$r = explode(',', $s); foreach ($r as &$i) $i = (int) $i;
Он имеет ту же производительность, что и метод 3.