$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 раза быстрее, чем explode()
, 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);
Я придумал это как модификацию ответа Марка. Это все еще использует функцию 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.
array_map(function($v){ return (int)$v; }, $strings_array);
это то, что я имел ввиду
Используйте этот код с закрытием (введенный в 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' ) );
В решении Mark вы вернете array([0]=> int 0)
, если попытаетесь проанализировать строку, такую как "тест".
Не уверен, что если это происходит быстрее, но при повторном массиве массив дважды набрасывает числовые строки на целые числа:
$string = "1,2,3, bla";
$ids = array_flip(array_flip(explode(',', $string)));
var_dump($ids);
Если у вас есть массив вроде:
$runners = ["1","2","3","4"];
И если вы хотите скрыть их целыми числами и сохранить их в массиве, выполните следующие действия:
$newArray = array_map( create_function('$value', 'return (int)$value;'),
$runners);
Альтернативным более коротким способом может быть:
$r = explode(',', $s);
foreach ($r as &$i) $i = (int) $i;
Он имеет ту же производительность, что и метод 3.
Держите его простым...
$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
Таким образом, == может решить вашу проблему, эффективен, но будет нарушен, если вы используете === в сравнении.
Если у вас многомерный массив, ни один из ранее упомянутых решений не будет работать. Вот мое решение:
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]
(Это будет работать с любым уровнем глубины)
Вы можете конвертировать значения в массиве:
<?php
$ids = explode(',', $strings);
foreach ($ids as $index => $value) {
$ids[$index] = (int)$value;
}
Вы также можете вернуть возвращаемое значение функции explode
в $strings
и выполнить итерацию вместо использования другой переменной ($ ids).
Я думаю, что это решение - самый безопасный способ с лучшей производительностью.