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