$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));
これはexplode()
、array_map()
およびintval()
よりもほぼ3倍高速です。
$integerIDs = json_decode('[' . $string . ']', true);
そのため、多数の整数に対する回答に記載されているいくつかの方法のパフォーマンスについて興味がありました。
0から100までの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)
と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
一番下の行は平均です。最初の方法は100万の整数に対して少し遅くなったように見えますが、答えで述べたように方法2の3倍のパフォーマンス向上には気付きませんでした。私の場合は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のソリューションでは、 "test"のような文字列を解析しようとするとarray([0]=> int 0)
を返します。
$integerIDs = array_map( 'intval', array_filter( explode(',', $string), 'is_numeric' ) );
これが速いかどうかはわかりませんが、配列を2回フリップすると数値文字列が整数にキャストされます。
$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 ()
で行くことができます。人々はそれをどのように使用するかを投稿しました、それで私はここにそれを含めていません。
注: ===の代わりに==演算子を使用する場合、文字列値が引用符なしで有効な数値を形成していれば、自動的に数値(整数または倍精度)に変換されます。例えば:
$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)を使用する代わりにそれを繰り返すこともできます。
私はこの解決策が最高のパフォーマンスを得るための最も安全な方法だと思います。