以下代码:
$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
类型而不是 string
类型。有没有比使用 foreach
循环遍历数组并将每个 string
转换为 int
更好的方法?
您可以通过以下代码实现此目的,
$integerIDs = array_map('intval', explode(',', $string));
所以我对大量整数的答案中提到的一些方法的性能感到好奇。
准备
只需创建一个包含 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)
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
底线是平均值。对于 100 万个整数,第一种方法看起来要慢一些,但我没有注意到答案中所述方法 2 的 3 倍性能增益。事实证明,在我的情况下,foreach
循环是最快的。我已经用 Xdebug 完成了基准测试。
编辑:自从最初发布答案以来已经有一段时间了。澄清一下,基准测试是在 php 5.6.40 中完成的。
array_map(function($v){ return (int)$v; }, $strings_array);
这就是我的意思
Convert a comma-delimited string into array of integers?
。我想我对此的理解是Convert a string of comma-delimited integers into array of integers
(这似乎与其他响应者对这个问题的理解一致)。您声称问题是Convert array values from string to int
。我在 OP 帖子中没有看到他从一个数组开始。我确实在第一行代码中看到了 $string = "1,2,3"
,这意味着起始点是一串逗号分隔的整数。
这几乎比 explode()
、array_map()
和 intval()
快 3 倍:
$integerIDs = json_decode('[' . $string . ']', true);
float
数字而不仅仅是 integer
,这个答案也是有效的,而你们没有意识到这一点。
将此代码与闭包一起使用(在 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' ) );
另一种较短的方法可能是:
$r = explode(',', $s);
foreach ($r as &$i) $i = (int) $i;
它具有与方法 3 相同的性能。
我的解决方案是在回调函数的帮助下转换每个值:
$ids = array_map( function($value) { return (int)$value; }, $ids )
$ids = \array_map(fn(string $id): int => (int) $id, $ids);
- PHP 7.4+ 更好
不确定这是否更快,但翻转数组两次会将数字字符串转换为整数:
$string = "1,2,3,bla";
$ids = array_flip(array_flip(explode(',', $string)));
var_dump($ids);
重要提示:如果您正在处理重复值,请不要使用它!
bla
转换为整数,所以它是不正确的,我必须 DV。这个答案不满足问题标题。
PHP 7.4 风格:
$ids = array_map(fn(string $x): int => (int) $x, explode(',', $string));
把事情简单化...
$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]]
这适用于任何深度级别。
或者,您可以使用 array_walk_recursive()
获得更短的答案:
array_walk_recursive($array, function(&$value){
$value = intval($value);
});
array
函数,它walk
recursive
可以通过叶节点。
array_walk_recursive
.... 这是一个“更短”的解决方案。忘记那个了,谢谢。 (添加到答案)
如果你有这样的数组:
$runners = ["1","2","3","4"];
如果你想将它们转换成整数并保存在数组中,下面应该做的工作:
$newArray = array_map( create_function('$value', 'return (int)$value;'),
$runners);
create_function
已被弃用,您可以改为这样做:$newArray = array_map(fn($value) => (int) $value, $runners)
$arr = ["adfsf", "*&^%$#^", "23", "25", "29"];
function convertArrayStringToArrayInt($arr)
{
$result = [];
foreach($arr as $value) {
if ((int)$value !== 0) {
$result[] = (int)$value;
}
}
return $result;
}
$result = convertArrayStringToArrayInt($arr);
var_dump($result);
结果会是这样
array(3) {
[0]=> int(23)
[1]=> int(25)
[2]=> int(29)
}
输入 => '["3","6","16","120"]'
我使用的类型转换 => (int)$s;
function Str_Int_Arr($data){
$h=[];
$arr=substr($data,1,-1);
//$exp=str_replace( ",","", $arr);
$exp=str_replace( "\"","", $arr);
$s='';
$m=0;
foreach (str_split($exp) as $k){
if('0'<= $k && '9'>$k || $k =","){
if('0' <= $k && '9' > $k){
$s.=$k;
$h[$m]=(int)$s;
}else{
$s="";
$m+=1;
}
}
}
return $h;
}
var_dump(Str_Int_Arr('["3","6","16","120"]'));
输出:
array(4) {
[0]=>
int(3)
[1]=>
int(6)
[2]=>
int(16)
[3]=>
int(120)
}
谢谢
<?php
$string = "1,2,3";
$ids = explode(',', $string );
array_walk( $ids, function ( &$id )
{
$id = (int) $id;
});
var_dump( $ids );
我很惊讶没有人提出 filter_var
方法,我不确定它在大型数据集上的表现如何,但如果你的关键是有效性超过性能,这里是一个例子:
$sampleString = '1,2 3, 4, 6, 5 , a';
$filteredValues = filter_var(
explode(',', $sampleString),
FILTER_VALIDATE_INT,
FILTER_NULL_ON_FAILURE | FILTER_FORCE_ARRAY
);
array (size=6)
0 => int 1
1 => null
2 => int 4
3 => int 6
4 => int 5
5 => null
如您所见,2 3
不是与 a
相同的有效数字,而是替换为 null
要摆脱空值,您可以应用 array_filter
$filteredValues = array_filter($filteredValues);
这将产生以下结果:
array (size=4)
0 => int 1
2 => int 4
3 => int 6
4 => int 5
另一种技术是在分解字符串后将输入值提示(强制)为 int
类型。
请注意,除非您拥有 set php to use strict typing,否则这些技术将按照我的演示链接中演示的方式工作。
以下技术不应用于清理非数字字符串;它假定所有值都是数字。
如果将浮点值传递给这些技术,它们将被截断/取整为整数。
代码:(Demo)
$string = "1,2,3";
$array = explode(',', $string);
var_dump($array);
echo "\n---\n";
array_walk($array, function(int &$int){;});
var_dump($array);
echo "\n---\n";
var_dump(
array_map(function(int $i){ return $i; }, explode(',', $string))
);
echo "\n---\n";
var_dump(
array_map(fn(int $i) => $i, explode(',', $string)) // PHP 7.4 arrow function syntax
);
输出:
array(3) {
[0]=> string(1) "1"
[1]=> string(1) "2"
[2]=> string(1) "3"
}
---
array(3) {
[0]=> int(1)
[1]=> int(2)
[2]=> int(3)
}
---
array(3) {
[0]=> int(1)
[1]=> int(2)
[2]=> int(3)
}
---
array(3) {
[0]=> int(1)
[1]=> int(2)
[2]=> int(3)
}
intval()
将是更好的解决方案,这已经是公认的答案,所以这个答案不会增加任何价值。