Wie konvertiere ich Array-Werte von String nach Int?

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

kehrt zurück

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

Ich brauche, dass die Werte vom Typ int statt vom Typ string sind. Gibt es eine bessere Möglichkeit, dies zu tun, als das Array mit einem foreach zu durchlaufen und jeden String in int zu konvertieren?

cwal
quelle

Antworten:

537

Sie können dies erreichen, indem Sie dem folgenden Code folgen:

$integerIDs = array_map('intval', explode(',', $string));
Mark Baker
quelle
3
aber wenn Sie Zeichenfolge 'Test' haben, erhalten Sie: Array ([0] => 0)
Dmitry Dubovitsky
10
@Dmitry - das ist richtig ... es ist eine Antwort auf die Frage des OP, nicht in jedem Fall eine 100% perfekte Antwort auf jede mögliche verwandte Frage. OP hatte eine Folge von durch Kommas getrennten numerischen Werten, keine Auswahl aus Text und Zahlen
Mark Baker
1
Verwenden Sie array_filter ($ array, 'is_numeric') besser, aber es kann nicht 100% wahr sein, da '0x539', '0b01011' numerische Werte sind.
Dmitry Dubovitsky
35
@Dmitry - Wenn Sie eine 18 Monate alte Antwort auf eine bestimmte Frage kritisieren möchten, weil sie nicht unter allen denkbaren Umständen perfekt ist, und der Meinung sind, dass Sie eine bessere Lösung haben, können Sie diese Frage gerne selbst beantworten warum deine Antwort besser ist ... niemand hält dich auf ... aber lass diese Antwort so wie sie ist
Mark Baker
intval () ist weniger performant als (int) cast. Verwenden Sie also besser eine andere Lösung mit (int). siehe Methode 3 hier
Fabian Picone
43

Das ist fast 3 - mal schneller als explode(), array_map()und intval():

$integerIDs = json_decode('[' . $string . ']', true);
sgrodzicki
quelle
1
@ Binod Ihre Zeichenfolge hat wahrscheinlich einen Syntaxfehler. Es sollte folgendermaßen formatiert sein: $ string = "1,2,3";
sgrodzicki
4
explode () + array_map () + intval () ist möglicherweise nicht so schnell wie json_decode (), aber es ist eindeutig nicht die bessere Option, um zu wählen ... Sie müssen andere Dinge wie json-Syntaxfehler behandeln, die wahrscheinlich sind, wenn Sie es sind Bereinigung von Benutzereingaben
staabm
2
Das ist schrecklich, besonders wenn es schneller ist als eine Karte + to_int! PHP, wie konnte es so weit gekommen sein ...
Phoet
3
Dies ist nur eine Mikrooptimierung. Es ist nicht erforderlich, eine so kleine Operation wie das Umwandeln eines mit Zeichenfolgen gefüllten Arrays in Ganzzahlen zu optimieren. Und wenn Ihr Array viele, viele Elemente enthält (z. B. Hunderttausende von Elementen), gibt es in Ihrem Projekt ein anderes, viel größeres Problem als diese Operation.
Andreas
1
@Andreas sieht nicht aus wie Mikro - Optimierung zu mir: blackfire.io/profiles/compare/...
sgrodzicki
41

Daher war ich neugierig auf die Leistung einiger der in den Antworten genannten Methoden für eine große Anzahl von Ganzzahlen.

Vorbereitung

Ich habe nur ein Array von 1 Million zufälligen Ganzzahlen zwischen 0 und 100 erstellt. Dann habe ich sie implodiert, um die Zeichenfolge zu erhalten.

  $integers = array();

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

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

Methode 1

Dies ist der einzige Liner aus Marks Antwort:

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

Methode 2

Dies ist der JSON-Ansatz:

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

Methode 3

Ich habe mir diese als Modifikation von Marks Antwort ausgedacht. Dies verwendet immer noch die explode()Funktion, aber anstatt aufzurufen, verwende array_map()ich eine reguläre foreachSchleife, um die Arbeit zu erledigen und den Overhead zu vermeiden array_map(). Ich analysiere auch mit (int)vs intval(), aber ich habe beide ausprobiert, und es gibt keinen großen Unterschied in Bezug auf die Leistung.

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

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

Ergebnisse:

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

Das Endergebnis ist der Durchschnitt. Es sieht so aus, als ob die erste Methode für 1 Million Ganzzahlen etwas langsamer war, aber ich habe keinen dreifachen Leistungsgewinn von Methode 2 bemerkt, wie in der Antwort angegeben. Es stellte sich heraus, dass die foreachSchleife in meinem Fall die schnellste war. Ich habe das Benchmarking mit Xdebug durchgeführt.

Bearbeiten: Es ist eine Weile her, seit die Antwort ursprünglich veröffentlicht wurde. Zur Verdeutlichung wurde der Benchmark in PHP 5.6 durchgeführt.

MikeWu
quelle
1
Ich frage mich wirklich, ob die Leistung in PHP 7 gleich geblieben ist und noch merkwürdiger, wie Methode 1 array_map in Kombination mit Methode 3 Casting und Closure / anonymem Rückruf funktionieren würde ...
jave.web
array_map(function($v){ return (int)$v; }, $strings_array);das habe ich gemeint
jave.web
Ich habe einige Tests auf PHP7.2 mit foreach (Methode 1), array_map mit 'intval' (Methode 2) und array_map mit anonymer Funktion (Methode 3) in einem Array mit 10000000 Elementen durchgeführt. Ich kam zu dem Ergebnis, dass meine Methode 2 schneller ist (~ 0,6 s), dann Methode 3 (~ 0,75 s), dann Methode 1 (~ 1,1 s)
Gabriel Lima
20

Verwenden Sie diesen Code mit einem Abschluss (eingeführt in PHP 5.3), er ist etwas schneller als die akzeptierte Antwort und für mich ist die Absicht, ihn in eine Ganzzahl umzuwandeln, klarer:

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

Ausgabe wird sein:

array(4) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
}
Andreas
quelle
1
Laut dem Dokument ist dies auch schneller als die in anderen Antworten vorgeschlagene create_function.
Bis zum
1
@ Bis ja, du hast recht. Und create_function ist seit PHP 7.2.0 veraltet.
Andreas
14

In Marks Lösung kehren Sie zurück, array([0]=> int 0)wenn Sie versuchen, eine Zeichenfolge wie "test" zu analysieren.

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

Sie sind sich nicht sicher, ob dies schneller ist, aber wenn Sie das Array zweimal umdrehen, werden numerische Zeichenfolgen in Ganzzahlen umgewandelt:

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

Eine alternative kürzere Methode könnte sein:

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

Es hat die gleiche Leistung wie Methode 3.

MyGeertRo
quelle
Die kürzeste und dennoch flexible Lösung für mich.
Ryan Arief
5

Wenn Sie ein Array haben wie:

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

Und wenn Sie sie in Ganzzahlen umwandeln und innerhalb des Arrays bleiben möchten, sollten Sie Folgendes tun:

$newArray = array_map( create_function('$value', 'return (int)$value;'),
            $runners);
star18bit
quelle
create_function ist seit PHP 7.2.0 veraltet. Überprüfen Sie besser meine Antwort ohne create_function, aber mit einer anonymen Funktion.
Andreas
4

Meine Lösung besteht darin, jeden Wert mithilfe der Rückruffunktion umzuwandeln:

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

Halte es einfach...

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

Warum suchst du nach anderen Wegen? Looping macht den Job ohne Schmerzen. Wenn Leistung Ihr Anliegen ist, können Sie mit gehenjson_decode () . Die Leute haben geschrieben, wie man das benutzt, deshalb füge ich es hier nicht ein.

Hinweis: Wenn Sie den Operator == anstelle von === verwenden, werden Ihre Zeichenfolgenwerte automatisch in Zahlen (z. B. Ganzzahl oder Doppel) konvertiert, wenn sie eine gültige Zahl ohne Anführungszeichen bilden. Beispielsweise:

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

Somit kann == Ihr Problem lösen, ist effizient, bricht jedoch ab, wenn Sie === in Vergleichen verwenden.

Devashish Jaiswal
quelle
2

Wenn Sie ein mehrdimensionales Array haben, funktioniert keine der zuvor genannten Lösungen. Hier ist meine Lösung:

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

Dann machen Sie einfach Folgendes:

arrayValuesToInt($multiDimentionalArray);

Dadurch wird ein Array wie folgt erstellt:

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

sieht aus wie das:

[[1,2][3,4]

(Dies funktioniert mit jeder Tiefe)

Skeets
quelle
1

Sie können Werte im Array konvertieren:

<?php

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

Sie können auch den Rückgabewert der explodeFunktion an zurückgeben$strings und iterieren, anstatt eine andere Variable ($ ids) zu verwenden.

Ich denke, diese Lösung ist der sicherste Weg mit der besten Leistung.

Roham Rafii
quelle
1

PHP 7.4 Stil:

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

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

Typkonvertierung, die ich verwendet habe => (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"]'));

Ausgabe:

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

Vielen Dank

Manoj Kumar
quelle