dizi değerleri dizeden int dönüştürmek nasıl?


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

İadeler

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

Değerler yerine yazım dizesi yerine int olması gerekir. Bunu bir foreach ile dizi döngü ve her dize int dönüştürmek daha iyi bir yolu var mı?

Yanıtlar:


537

Bunu aşağıdaki kodu takip ederek yapabilirsiniz,

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

3
ancak 'test' dizeniz varsa, şunu aldınız: array ([0] => 0)
Dmitry Dubovitsky

10
@Dmitry - bu doğru ... Bu OP'nin sorusuna bir cevap, her durumda ilgili potansiyel soruya% 100 mükemmel değil. OP, metin ve sayıların bir toplaması ve karışımı değil, virgülle ayrılmış sayısal değerler dizesine sahipti
Mark Baker

1
array_filter ($ array, 'is_numeric') kullanın, ancak '0x539', '0b01011' sayısal değerler olduğu için% 100 doğru olamaz.
Dmitry Dubovitsky

35
@Dmitry - akla gelebilecek her durumda mükemmel olmadığı için belirli bir soruya 18 aylık bir cevabı eleştirmek istiyorsanız ve daha iyi bir çözümünüz olduğunu düşünüyorsanız, bu soruya kendi cevabınızı eklemekten çekinmeyin, açıklayın cevabınız neden daha iyi ... kimse sizi durdurmuyor ... ama bu cevabı olduğu gibi bırakın
Mark Baker

intval (), (int) ' den daha az performans gösterir . Yani (int) ile başka bir çözüm daha iyi. bkz. Yöntem 3
Fabian Picone

43

Bu neredeyse 3 kat daha hızlı olduğunu explode(), array_map()ve intval():

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

1
@Binod dizinizde muhtemelen bir sözdizimi hatası var. Şu şekilde biçimlendirilmelidir: $ string = "1,2,3";
sgrodzicki

4
explode () + array_map () + intval (), json_decode () kadar hızlı olmayabilir, ancak seçmek için daha iyi bir seçenek değildir ... sanitizing kullanıcı girişi
staabm

2
Bu, özellikle bir haritadan daha hızlı olduğunda korkunç! nasıl bu kadar gelmiş olabilir ...
phoet

3
Bu sadece mikro optimizasyon. Dizelerle dolu bir diziyi tamsayılara dönüştürmek gibi küçük bir işlemi optimize etmeye gerek yoktur. Diziniz çok sayıda öğe içeriyorsa (örneğin yüz binlerce öğe), projenizde bu işlemden daha büyük bir sorun daha vardır.
Andreas

1
@Andreas bana mikro optimizasyon gibi görünmüyor: blackfire.io/profiles/compare/…
sgrodzicki

41

Bu nedenle, çok sayıda tamsayı için verilen cevaplarda belirtilen yöntemlerin bazılarının performansını merak ettim.

Hazırlık

Sadece 0 ile 100 arasında 1 milyon rastgele tamsayı bir dizi oluşturmak. Daha sonra, ben dize almak için onları imploded.

  $integers = array();

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

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

Yöntem 1

Mark'ın cevabındaki tek astar:

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

Yöntem 2

JSON yaklaşımı budur:

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

Yöntem 3

Bunu Mark'ın cevabının modifikasyonu olarak buldum. Bu hala explode()işlevini kullanıyor , ancak çağırmak yerine array_map()düzenli foreachdöngü kullanarak yükü önlemek için iş yapmak array_map()zorundayım olabilir. Ayrıca (int)vs ile ayrıştırıyorum intval(), ama ikisini de denedim ve performans açısından çok fazla fark yok.

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

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

Sonuçlar:

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

Sonuç olarak ortalama. İlk yöntemin 1 milyon tamsayı için biraz daha yavaş olduğu görülüyor, ancak yanıtta belirtildiği gibi Yöntem 2'nin 3 kat performans kazancı fark etmedim. foreachBenim durumumda en hızlı olan döngü olduğu ortaya çıktı . Ben Xdebug ile kıyaslama yaptım.

Düzenleme: Cevabın asıl yayınlanmasından bu yana bir süre geçti. Açıklığa kavuşturmak için, karşılaştırma ölçütü php 5.6'da yapılmıştır.


1
Gerçekten performans PHP 7 aynı kaldı olup olmadığını merak ediyorum ve nasıl Yöntem 1 dizi_map yöntem 3 döküm ve kapatma / anonim geri arama ile birlikte nasıl yapacağını merak ediyorum ...
jave.web

array_map(function($v){ return (int)$v; }, $strings_array);demek istediğim bu
jave.web

Ben for000 (yöntem 1), 'intval' ile dizi_map (yöntem 2) ve 10000000 elemanları ile bir dizide anonim işlevi (yöntem 3) ile dizi_map kullanarak PHP7.2 üzerinde bazı testler yaptım. Benim yöntem 2 daha hızlı (~ 0.6s), sonra yöntem 3 (~ 0.75s), sonra yöntem 1 (~ 1.1s)
Gabriel Lima

20

Bu kodu bir kapakla (tanıtıldığında PHP 5.3) kullanın, kabul edilen cevaptan biraz daha hızlı ve benim için bunu bir tamsayıya aktarma niyeti daha açık:

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

Çıktı:

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

1
Göre doc , bu daha hızlı diğer yanıtlar önerilen create_function daha da olduğunu.
kadar

1
@untill Evet, haklısın. Ve create_function PHP 7.2.0'dan beri kullanımdan kaldırılmıştır.
Andreas

14

Mark'ın çözümünde, array([0]=> int 0)"test" gibi bir dizeyi ayrıştırmaya çalışırsanız geri dönersiniz .

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

7

Bunun daha hızlı olup olmadığından emin değil ancak diziyi iki kez çevirmek sayısal dizeleri tamsayılara dönüştürür:

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

7

Alternatif kısa bir yöntem şunlar olabilir:

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

Yöntem 3 ile aynı performansa sahiptir.


benim için en kısa ama esnek çözüm.
Ryan Arief

5

Gibi bir diziniz varsa:

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

Ve bunları tamsayılara dönüştürmek ve dizi içinde tutmak istiyorsanız, aşağıdakileri yapmalısınız:

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

create_function PHP 7.2.0'dan beri kullanımdan kaldırıldı. Cevabımı create_function olmadan, ancak anonim bir işlevle daha iyi kontrol et.
Andreas

4

Benim çözüm geri arama fonksiyonu yardımı ile her değeri döküm:

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

3

Basit tutun ...

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

Neden başka yollar arıyorsun? Döngü işi ağrısız yapar. Performans endişenizse, devam edebilirsiniz json_decode (). İnsanlar bunu nasıl kullanacaklarını yayınladılar, bu yüzden buraya dahil etmiyorum.

Not: === yerine == operatörünü kullanırken, dize değerleriniz tırnak işaretleri olmadan geçerli bir sayı oluşturuyorsa otomatik olarak sayılara (örneğin tamsayı veya çift) dönüştürülür. Örneğin:

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

Bu nedenle, == sorununuzu çözebilir, etkilidir, ancak karşılaştırmalarda === kullanırsanız kırılır.


2

Çok boyutlu bir diziniz varsa, daha önce belirtilen çözümlerin hiçbiri çalışmaz. İşte benim çözümüm:

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

Ardından, bunu yapın:

arrayValuesToInt($multiDimentionalArray);

Bu şöyle bir dizi yapar:

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

Bunun gibi:

[[1,2][3,4]

(Bu herhangi bir derinlikte çalışacaktır)


1

Dizideki değerleri dönüştürebilirsiniz:

<?php

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

Ayrıca dönüş değeri döndürebilir explodeiçin fonksiyonu $stringsve tekrarlayın yerine başka bir değişken ($ kimlikleri) kullanma.

Bu çözümün en iyi performansla en güvenli yol olduğunu düşünüyorum.


1

PHP 7.4 stili:

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

0

Giriş => '["3", "6", "16", "120"]'

Kullandığım tür dönüşümü => (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"]'));

Çıktı:

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

Teşekkürler

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.