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?

Antworten:


537

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

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

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

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.


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

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

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

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.


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

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 )

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.


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)


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.


1

PHP 7.4 Stil:

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

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.