jak przekonwertować wartości tablic z ciągu na int?


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

zwroty

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

Potrzebuję, aby wartości były typu int zamiast ciągu typu. Czy istnieje lepszy sposób na zrobienie tego niż zapętlanie tablicy za pomocą foreach i konwertowanie każdego łańcucha na int?

Odpowiedzi:


537

Możesz to osiągnąć, postępując zgodnie z kodem,

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

3
ale jeśli masz ciąg „test”, masz: tablicę ([0] => 0)
Dmitry Dubovitsky

10
@Dmitry - zgadza się ... to odpowiedź na pytanie PO, a nie w 100% doskonała w każdym przypadku odpowiedź na każde potencjalne powiązane pytanie. OP miał ciąg wartości liczbowych oddzielonych przecinkami, a nie kombinację tekstu i liczb
Mark Baker,

1
lepiej użyj array_filter ($ array, 'is_numeric'), ale nie może być w 100% prawdą, ponieważ „0x539”, „0b01011” to wartości liczbowe.
Dmitrij Dubowicki

35
@Dmitry - jeśli chcesz skrytykować 18-miesięczną odpowiedź na konkretne pytanie, ponieważ nie jest ona idealna w każdych możliwych okolicznościach i uważasz, że masz lepsze rozwiązanie, możesz dodać własną odpowiedź na to pytanie, wyjaśniając dlaczego twoja odpowiedź jest lepsza .... nikt cię nie powstrzymuje ... ale zostaw tę odpowiedź taką, jaka jest
Mark Baker

intval () jest mniej wydajny niż rzutowanie (int) . Lepiej więc użyj innego rozwiązania z (int). patrz Metoda 3 tutaj
Fabian Picone

43

To jest prawie 3 razy szybciej niż explode(), array_map()i intval():

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

1
@Binod Twój łańcuch prawdopodobnie ma błąd składniowy. Powinien być sformatowany w następujący sposób: $ string = "1,2,3";
sgrodzicki

4
explode () + array_map () + intval () może nie być tak szybki jak json_decode (), ale najwyraźniej nie jest lepszą opcją do wyboru ... musisz obsługiwać inne rzeczy, takie jak błędy składniowe json, które są prawdopodobne, gdy jesteś dezynfekowanie danych wejściowych użytkownika
staabm

2
to jest okropne, szczególnie gdy jest szybsze niż mapa + to_int! php, jak mogło dojść tak daleko ...
phoet

3
To tylko mikrooptymalizacja. Nie ma potrzeby optymalizacji tak drobnej operacji, jak rzutowanie tablicy wypełnionej ciągami znaków na liczby całkowite. A jeśli twoja tablica zawiera wiele elementów (np. Setki tysięcy elementów), oznacza to, że w twoim projekcie jest o wiele większy problem niż ta operacja.
Andreas,

1
@Andreas nie wygląda mi na mikrooptymalizację: blackfire.io/profiles/compare/…
sgrodzicki

41

Byłem więc ciekawy wydajności niektórych metod wymienionych w odpowiedziach na dużą liczbę liczb całkowitych.

Przygotowanie

Właśnie stworzyłem tablicę 1 miliona losowych liczb całkowitych od 0 do 100. Następnie zaimplodowałem je, aby uzyskać ciąg.

  $integers = array();

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

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

Metoda 1

To jest jedna linijka z odpowiedzi Marka:

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

Metoda 2

Oto podejście JSON:

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

Metoda 3

Wymyśliłem ten jako modyfikację odpowiedzi Marka. To wciąż jest używaneexplode() funkcji, ale zamiast wywoływać array_map(), używam regularnej foreachpętli, aby wykonać pracę, aby uniknąć narzutu array_map(). Parsuję też z (int)vs intval(), ale wypróbowałem oba, i nie ma dużej różnicy pod względem wydajności.

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

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

Wyniki:

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

Dolna linia to średnia. Wygląda na to, że pierwsza metoda była nieco wolniejsza dla 1 miliona liczb całkowitych, ale nie zauważyłem 3-krotnego wzrostu wydajności metody 2, jak stwierdzono w odpowiedzi. Okazało sięforeach pętla była najszybsza w moim przypadku. Przeprowadziłem testy porównawcze z Xdebug.

Edycja: Minęło trochę czasu, odkąd pierwotnie opublikowano odpowiedź. Aby to wyjaśnić, test został przeprowadzony w php 5.6.


1
Naprawdę zastanawiam się, czy wydajność pozostała niezmieniona w PHP 7, a jeszcze bardziej ciekawe, jak miałaby metoda metoda array_map w połączeniu z rzutowaniem metody 3 i zamykaniem / anonimowym wywołaniem zwrotnym ...
jave.web

array_map(function($v){ return (int)$v; }, $strings_array);o to mi chodziło
jave.web

Zrobiłem kilka testów na PHP7.2 przy użyciu foreach (metoda 1), array_map z 'intval' (metoda 2) i array_map z anonimową funkcją (metoda 3) w tablicy z 10000000 elementów. Doszedłem do wniosku, że moja metoda 2 jest szybsza (~ 0,6 s), następnie metoda 3 (~ 0,75 s), a następnie metoda 1 (~ 1,1 s)
Gabriel Lima

20

Użyj tego kodu z zamknięciem (wprowadzonym w PHP 5.3), jest to nieco szybsze niż zaakceptowana odpowiedź, a dla mnie zamiar przekazania go na liczbę całkowitą jest wyraźniejszy:

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

Dane wyjściowe będą:

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

1
Według doktora jest to również szybsze niż funkcja create_funkcji zaproponowana w innych odpowiedziach.
do

1
@untill Tak, masz rację. A funkcja create_function jest przestarzała od PHP 7.2.0.
Andreas

14

W rozwiązaniu Marka wrócisz, array([0]=> int 0)jeśli spróbujesz parsować ciąg taki jak „test”.

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

7

Nie jestem pewien, czy jest to szybsze, ale dwukrotne odwrócenie tablicy spowoduje rzut ciągów liczbowych na liczby całkowite:

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

7

Alternatywną krótszą metodą może być:

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

Ma taką samą wydajność jak metoda 3.


najkrótsze, ale elastyczne rozwiązanie dla mnie.
Ryan Arief,

5

Jeśli masz tablicę typu:

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

A jeśli chcesz ukryć je w liczbach całkowitych i zachować w obrębie tablicy, wykonaj następujące czynności:

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

Funkcja create_function jest przestarzała od PHP 7.2.0. Lepiej sprawdź moją odpowiedź bez funkcji create_function, ale z anonimową funkcją.
Andreas

4

Moje rozwiązanie rzuca każdą wartość za pomocą funkcji zwrotnej:

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

3

Nie komplikuj...

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

Dlaczego szukasz innych sposobów? Pętla wykonuje pracę bez bólu. Jeśli zależy Ci na wydajności, możesz iść dalej json_decode (). Ludzie napisali, jak z tego korzystać, więc nie zamieszczam go tutaj.

Uwaga: W przypadku użycia operatora == zamiast === wartości ciągu są automatycznie konwertowane na liczby (np. Liczba całkowita lub podwójna), jeśli tworzą poprawną liczbę bez cudzysłowów. Na przykład:

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

Tak więc == może rozwiązać twój problem, jest wydajny, ale zepsuje się, jeśli użyjesz === w porównaniach.


2

Jeśli masz tablicę wielowymiarową, żadne z wcześniej wymienionych rozwiązań nie będzie działać. Oto moje rozwiązanie:

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

Następnie zrób to:

arrayValuesToInt($multiDimentionalArray);

Spowoduje to utworzenie takiej tablicy:

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

wygląda jak to:

[[1,2][3,4]

(Będzie to działać na dowolnym poziomie głębokości)


1

Możesz przekonwertować wartości w tablicy:

<?php

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

Możesz także zwrócić wartość zwracaną przez explodefunkcję do$strings i iterować ją zamiast używać innej zmiennej ($ ids).

Myślę, że to rozwiązanie jest najbezpieczniejszym sposobem z najlepszą wydajnością.


1

Styl PHP 7.4:

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

0

Wejście => „[„ 3 ”,„ 6 ”,„ 16 ”,„ 120 ”]”

Konwersja typu, którego użyłem => (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"]'));

Wynik:

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

Dzięki

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.