¿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?

Respuestas:


537

Puede lograr esto siguiendo el código,

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

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

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.


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)
}

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

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

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.


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

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 )

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.


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)


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.


1

Estilo PHP 7.4:

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

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.