¿Cómo convertir valores de matriz de cadena a int?

233
$string = "1,2,3"
$ids = explode(',', $string);
var_dump($ids);

devoluciones

array(3) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(1) "3"
}

Necesito que los valores sean de tipo int en lugar de tipo string. ¿Hay una mejor manera de hacer esto que recorrer la matriz con un foreach y convertir cada cadena a int?

cwal
fuente

Respuestas:

537

Puede lograr esto siguiendo el código,

$integerIDs = array_map('intval', explode(',', $string));
Mark Baker
fuente
3
pero si tiene 'prueba' de cadena, obtendrá: array ([0] => 0)
Dmitry Dubovitsky
10
@Dmitry: así es ... es una respuesta a la pregunta del OP, no una respuesta 100% perfecta en todos los casos a cada pregunta relacionada potencial. OP tenía una cadena de valores numéricos separados por comas, no una combinación de texto y números
Mark Baker,
1
use array_filter ($ array, 'is_numeric') mejor, pero no puede ser 100% verdadero, porque '0x539', '0b01011' son valores numéricos.
Dmitry Dubovitsky
35
@Dmitry: si desea criticar una respuesta de 18 meses a una pregunta específica porque no es perfecta en todas las circunstancias imaginables, y cree que tiene una mejor solución, no dude en agregar su propia respuesta a esta pregunta, explicando por qué su respuesta es mejor ... nadie lo detiene ... pero deje esta respuesta como está
Mark Baker
intval () tiene menos rendimiento que (int) cast. Así que mejor usa otra solución con (int). ver Método 3 aquí
Fabian Picone
43

Esto es casi 3 veces más rápido que explode(), array_map()y intval():

$integerIDs = json_decode('[' . $string . ']', true);
sgrodzicki
fuente
1
@Binod su cadena tiene probablemente un error de sintaxis. Debe tener el siguiente formato: $ string = "1,2,3";
sgrodzicki
44
explotar () + array_map () + intval () podría no ser tan rápido como json_decode (), pero claramente no es la mejor opción para elegir ... necesita manejar otras cosas como errores de sintaxis json que son probables cuando está desinfección de entrada del usuario
staabm
2
¡Esto es horrible, especialmente cuando es más rápido que un mapa + to_int! php, ¿cómo podría haber llegado tan lejos ...
phoet
3
Esto es solo micro optimización. No es necesario optimizar una operación tan pequeña como convertir una matriz llena de cadenas a enteros. Y si su matriz contiene muchos elementos (por ejemplo, cientos de miles de elementos), entonces hay otro problema mucho más grande en su proyecto que esta operación.
Andreas
1
@Andreas no me parece una micro optimización: blackfire.io/profiles/compare/…
sgrodzicki
41

Así que tenía curiosidad sobre el rendimiento de algunos de los métodos mencionados en las respuestas para una gran cantidad de enteros.

Preparación

Simplemente creando una matriz de 1 millón de enteros aleatorios entre 0 y 100. Luego, les imploré que obtuvieran la cadena.

  $integers = array();

  for ($i = 0; $i < 1000000; $i++) {
      $integers[] = rand(0, 100);
  }

  $long_string = implode(',', $integers);

Método 1

Este es el revestimiento de la respuesta de Mark:

$integerIDs = array_map('intval', explode(',', $long_string));

Método 2

Este es el enfoque JSON:

  $integerIDs = json_decode('[' . $long_string . ']', true);

Método 3

Se me ocurrió esta como modificación de la respuesta de Mark. Esto todavía está usando la explode()función, pero en lugar de llamar array_map(), estoy usando un foreachbucle regular para hacer el trabajo para evitar la sobrecarga array_map(). También estoy analizando con (int)vs intval(), pero probé ambos, y no hay mucha diferencia en términos de rendimiento.

  $result_array = array();
  $strings_array = explode(',', $long_string);

  foreach ($strings_array as $each_number) {
      $result_array[] = (int) $each_number;
  }

Resultados:

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

El resultado final es el promedio. Parece que el primer método fue un poco más lento para 1 millón de enteros, pero no noté una ganancia de rendimiento 3 veces superior al Método 2 como se indica en la respuesta. Resultó que el foreachbucle fue el más rápido en mi caso. He hecho el benchmarking con Xdebug.

Editar: ha pasado un tiempo desde que la respuesta se publicó originalmente. Para aclarar, el punto de referencia se realizó en php 5.6.

MikeWu
fuente
1
Realmente me pregunto si el rendimiento se mantuvo igual en PHP 7, y aún más curioso cómo sería el método 1 array_map combinado con el método 3 de conversión y cierre / devolución de llamada anónima ...
jave.web
array_map(function($v){ return (int)$v; }, $strings_array);esto es lo que quise decir
jave.web
Hice algunas pruebas en PHP7.2 usando foreach (método 1), array_map con 'intval' (método 2) y array_map con función anónima (método 3) en una matriz con 10000000 elementos. Se me ocurrieron los resultados de que mi método 2 es más rápido (~ 0.6s), luego el método 3 (~ 0.75s), luego el método 1 (~ 1.1s)
Gabriel Lima
20

Use este código con un cierre (introducido en PHP 5.3), es un poco más rápido que la respuesta aceptada y para mí, la intención de convertirlo en un número entero es más clara:

// 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);

La salida será:

array(4) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
}
Andreas
fuente
1
Según el documento , esto también es más rápido que create_function propuesto en otras respuestas.
hasta el
1
@ hasta Sí, tienes razón. Y create_function está en desuso desde PHP 7.2.0.
Andreas
14

En la solución de Mark, volverá array([0]=> int 0)si intenta analizar una cadena como "prueba".

$integerIDs = array_map( 'intval', array_filter( explode(',', $string), 'is_numeric' ) );
Dmitry Dubovitsky
fuente
7

No estoy seguro de si esto es más rápido, pero voltear la matriz dos veces arrojará cadenas numéricas a enteros:

$string = "1,2,3, bla";
$ids = array_flip(array_flip(explode(',', $string)));
var_dump($ids);
baikho
fuente
7

Un método alternativo más corto podría ser:

$r = explode(',', $s);
foreach ($r as &$i) $i = (int) $i;

Tiene el mismo rendimiento que el Método 3.

MyGeertRo
fuente
La solución más corta pero flexible para mí.
Ryan Arief
5

Si tienes una matriz como:

$runners = ["1","2","3","4"];

Y si desea convertirlos en enteros y mantenerlos dentro de la matriz, lo siguiente debería hacer el trabajo:

$newArray = array_map( create_function('$value', 'return (int)$value;'),
            $runners);
star18bit
fuente
create_function está en desuso desde PHP 7.2.0. Mejor revise mi respuesta sin create_function, pero con una función anónima.
Andreas
4

Mi solución es convertir cada valor con la ayuda de la función de devolución de llamada:

$ids = array_map( function($value) { return (int)$value; }, $ids )
Theva
fuente
3

Mantenlo simple...

$intArray = array ();
$strArray = explode(',', $string);
foreach ($strArray as $value)
$intArray [] = intval ($value);

¿Por qué buscas otras formas? Looping hace el trabajo sin dolor. Si el rendimiento es su preocupación, puede seguir adelante json_decode (). La gente ha publicado cómo usar eso, así que no lo incluyo aquí.

Nota: Al usar el operador == en lugar de ===, los valores de su cadena se convierten automáticamente en números (por ejemplo, entero o doble) si forman un número válido sin comillas. Por ejemplo:

$str = '1';
($str == 1) // true but
($str === 1) //false

Por lo tanto, == puede resolver su problema, es eficiente, pero se romperá si usa === en las comparaciones.

Devashish Jaiswal
fuente
2

Si tiene una matriz multidimensional, ninguna de las soluciones mencionadas anteriormente funcionará. Aquí está mi solución:

public function arrayValuesToInt(&$array){
  if(is_array($array)){
    foreach($array as &$arrayPiece){
      arrayValuesToInt($arrayPiece);
    }
  }else{
    $array = intval($array);
  }
}

Entonces, solo haz esto:

arrayValuesToInt($multiDimentionalArray);

Esto hará una matriz como esta:

[["1","2"]["3","4"]]

se parece a esto:

[[1,2][3,4]

(Esto funcionará con cualquier nivel de profundidad)

Esqueletos
fuente
1

Puede convertir valores en la matriz:

<?php

$ids = explode(',', $strings);
foreach ($ids as $index => $value) {
    $ids[$index] = (int)$value;
}

También puede devolver el valor de retorno de la explodefunción a$strings e iterarlo en lugar de usar otra variable ($ ids).

Creo que esta solución es la forma más segura con el mejor rendimiento.

Roham Rafii
fuente
1

Estilo PHP 7.4:

$ids = array_map(fn(string $x): int => (int) $x, explode(',', $string));
Julien
fuente
0

Entrada => '["3", "6", "16", "120"]'

Tipo de conversión que utilicé => (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"]'));

Salida:

array(4) {
  [0]=>
  int(3)
  [1]=>
  int(6)
  [2]=>
  int(16)
  [3]=>
  int(120)
}

Gracias

Manoj Kumar
fuente