come convertire i valori dell'array da stringa a int?


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

ritorna

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

Ho bisogno che i valori siano di tipo int anziché di tipo stringa. C'è un modo migliore per farlo che passare in rassegna l'array con un foreach e convertire ogni stringa in int?

Risposte:


537

Puoi raggiungere questo obiettivo seguendo il codice,

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

3
ma se hai la stringa 'test',
ottieni

10
@Dmitry - esatto .... è una risposta alla domanda del PO, non una risposta perfetta al 100% in ogni caso a ogni potenziale domanda correlata. OP aveva una stringa di valori numerici separati da virgola, non un pick-and mix di testo e numeri
Mark Baker

1
usa array_filter ($ array, 'is_numeric') meglio, ma non può essere vero al 100%, perché '0x539', '0b01011' sono valori numerici.
Dmitry Dubovitsky,

35
@Dmitry - se vuoi criticare una risposta di 18 mesi a una domanda specifica perché non è perfetta in ogni circostanza immaginabile e pensi di avere una soluzione migliore, quindi sentiti libero di aggiungere la tua risposta a questa domanda, spiegando perché la tua risposta è migliore ... nessuno ti sta fermando ... ma lascia questa risposta così com'è
Mark Baker

intval () è meno performante di (int) cast. Quindi meglio usare un'altra soluzione con (int). vedi il Metodo 3 qui
Fabian Picone,

43

Si tratta di quasi 3 volte più veloce rispetto explode(), array_map()e intval():

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

1
@Binod probabilmente la tua stringa ha un errore di sintassi. Dovrebbe essere formattato in questo modo: $ string = "1,2,3";
sgrodzicki,

4
explode () + array_map () + intval () potrebbe non essere veloce come json_decode () ma chiaramente non è l'opzione migliore per scegliere ... devi gestire altre cose come gli errori json-syntax che sono probabili quando lo sei sanificazione dell'input dell'utente
staabm

2
questo è orribile, specialmente quando è più veloce di una mappa + to_int! php, come è potuto arrivare così lontano ...
phoet,

3
Questa è solo micro ottimizzazione. Non è necessario ottimizzare un'operazione così piccola come il cast di un array pieno di stringhe in numeri interi. E se il tuo array contiene molti e molti elementi (ad esempio centinaia di migliaia di elementi), allora c'è un altro problema molto più grande nel tuo progetto rispetto a questa operazione.
Andreas,

1
@Andreas non mi sembra una micro ottimizzazione: blackfire.io/profiles/compare/…
sgrodzicki,

41

Quindi ero curioso delle prestazioni di alcuni dei metodi citati nelle risposte per un gran numero di numeri interi.

Preparazione

Sto solo creando un array di 1 milione di numeri casuali compresi tra 0 e 100. Quindi, li ho implosi per ottenere la stringa.

  $integers = array();

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

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

Metodo 1

Questo è l'unico esempio della risposta di Mark:

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

Metodo 2

Questo è l'approccio JSON:

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

Metodo 3

Ho pensato a questo come modifica della risposta di Mark. Questo sta ancora usando la explode()funzione, ma invece di chiamare array_map()sto usando un foreachciclo regolare per fare il lavoro per evitare che l'overhead array_map()possa avere. Sto anche analizzando il (int)vs intval(), ma ho provato entrambi, e non c'è molta differenza in termini di prestazioni.

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

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

risultati:

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

La linea di fondo è la media. Sembra che il primo metodo sia stato un po 'più lento per 1 milione di numeri interi, ma non ho notato un aumento delle prestazioni 3 volte del metodo 2, come indicato nella risposta. Si è scoperto che il foreachloop era il più veloce nel mio caso. Ho fatto il benchmarking con Xdebug.

Modifica: è passato un po 'di tempo da quando la risposta è stata pubblicata inizialmente. Per chiarire, il benchmark è stato fatto in php 5.6.


1
Mi chiedo davvero se le prestazioni rimarranno le stesse in PHP 7, e ancora più curioso come farebbe il metodo 1 array_map combinato con il metodo 3 casting e chiusura / callback anonimo ...
jave.web

array_map(function($v){ return (int)$v; }, $strings_array);questo è ciò che intendevo
jave.web,

Ho fatto alcuni test su PHP7.2 usando foreach (metodo 1), array_map con 'intval' (metodo 2) e array_map con funzione anonima (metodo 3) in un array con 10000000 elementi. Ho trovato i risultati che il mio metodo 2 è più veloce (~ 0.6s), quindi il metodo 3 (~ 0.75s), quindi il metodo 1 (~ 1.1s)
Gabriel Lima

20

Usa questo codice con una chiusura (introdotta in PHP 5.3), è un po 'più veloce della risposta accettata e per me, l'intenzione di lanciarlo su un numero intero, è più chiara:

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

L'output sarà:

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

1
Secondo il documento , questo è anche più veloce di create_function proposto in altre risposte.
fino a quando

1
@untill Sì, hai ragione. E create_function è obsoleto da PHP 7.2.0.
Andreas

14

Nella soluzione di Mark, tornerai array([0]=> int 0)se provi ad analizzare una stringa come "test".

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

7

Non sono sicuro se questo è più veloce, ma capovolgendo due volte l'array, verranno convertite stringhe numeriche in numeri interi:

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

7

Un metodo più breve alternativo potrebbe essere:

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

Ha le stesse prestazioni del Metodo 3.


la soluzione più breve ma flessibile per me.
Ryan Arief,

5

Se hai array come:

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

E se si desidera convertirli in numeri interi e mantenerli all'interno dell'array, attenersi alla seguente procedura:

$newArray = array_map( create_function('$value', 'return (int)$value;'),
            $runners);

create_function è obsoleto da PHP 7.2.0. Meglio dare un'occhiata alla mia risposta senza create_function, ma con una funzione anonima.
Andreas,

4

La mia soluzione sta lanciando ogni valore con l'aiuto della funzione di callback:

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

3

Keep it simple ...

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

Perché stai cercando altri modi? Il loop fa il lavoro senza dolore. Se la performance è la tua preoccupazione, puoi andare con json_decode (). Le persone hanno pubblicato come usarlo, quindi non lo includo qui.

Nota: quando si utilizza l'operatore == anziché ===, i valori della stringa vengono automaticamente convertiti in numeri (ad es. Numero intero o doppio) se formano un numero valido senza virgolette. Per esempio:

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

Pertanto, == può risolvere il problema, è efficiente, ma si romperà se si utilizza === nei confronti.


2

Se si dispone di un array multidimensionale, nessuna delle soluzioni menzionate in precedenza funzionerà. Ecco la mia soluzione:

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

Quindi, basta fare questo:

arrayValuesToInt($multiDimentionalArray);

Questo renderà un array come questo:

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

Assomiglia a questo:

[[1,2][3,4]

(Funzionerà con qualsiasi livello di profondità)


1

È possibile convertire i valori nell'array:

<?php

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

È inoltre possibile restituire il valore restituito della explodefunzione$strings e iterarlo anziché utilizzare un'altra variabile ($ ids).

Penso che questa soluzione sia il modo più sicuro con le migliori prestazioni.


1

Stile PHP 7.4:

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

0

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

Conversione del tipo che ho usato => (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"]'));

Produzione:

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

Grazie

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.