bagaimana cara mengkonversi nilai array dari string ke int?

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

kembali

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

Saya membutuhkan nilai-nilai untuk menjadi tipe int bukan tipe string. Apakah ada cara yang lebih baik untuk melakukan ini daripada mengulang melalui array dengan foreach dan mengubah setiap string ke int?

cwal
sumber

Jawaban:

537

Anda dapat mencapai ini dengan mengikuti kode,

$integerIDs = array_map('intval', explode(',', $string));
Mark Baker
sumber
3
tetapi jika Anda memiliki string 'test', Anda mendapat: array ([0] => 0)
Dmitry Dubovitsky
10
@Dmitry - benar .... itu adalah jawaban untuk pertanyaan OP, bukan 100% sempurna dalam setiap kasus jawaban untuk setiap pertanyaan terkait yang potensial. OP memiliki serangkaian nilai numerik yang dipisah koma, bukan pilihan dan campuran teks dan angka
Mark Baker
1
gunakan array_filter ($ array, 'is_numeric') lebih baik, tetapi itu tidak bisa 100% benar, karena '0x539', '0b01011' adalah nilai numerik.
Dmitry Dubovitsky
35
@Dmitry - jika Anda ingin mengkritik jawaban 18 bulan untuk pertanyaan tertentu karena tidak sempurna dalam setiap keadaan yang mungkin, dan berpikir Anda memiliki solusi yang lebih baik, maka jangan ragu untuk menambahkan jawaban Anda sendiri untuk pertanyaan ini, menjelaskan mengapa jawaban Anda lebih baik .... tidak ada yang menghentikan Anda ... tetapi biarkan jawaban ini apa adanya
Mark Baker
intval () kurang berkinerja daripada (int) pemain. Jadi lebih baik gunakan solusi lain dengan (int). lihat Metode 3 di sini
Fabian Picone
43

Ini hampir 3 kali lebih cepat daripada explode(), array_map()dan intval():

$integerIDs = json_decode('[' . $string . ']', true);
sgrodzicki
sumber
1
@Binod string Anda mungkin memiliki kesalahan sintaksis. Itu harus diformat seperti ini: $ string = "1,2,3";
sgrodzicki
4
explode () + array_map () + intval () mungkin tidak secepat json_decode () tetapi jelas bukan pilihan yang lebih baik untuk memilih ... Anda perlu menangani hal-hal lain seperti kesalahan json-sintaks yang mungkin terjadi saat Anda berada
membersihkan
2
ini mengerikan, terutama saat lebih cepat daripada peta + to_int! php, bagaimana mungkin sampai sejauh itu ...
phoet
3
Ini hanya optimasi mikro. Tidak perlu mengoptimalkan operasi sekecil itu seperti melemparkan array yang diisi dengan string ke integer. Dan jika array Anda mengandung banyak elemen (mis. Ratusan ribu elemen), maka ada masalah lain yang jauh lebih besar dalam proyek Anda daripada operasi ini.
Andreas
1
@Andreas tidak terlihat seperti optimasi mikro bagi saya: blackfire.io/profiles/compare/…
sgrodzicki
41

Jadi saya ingin tahu tentang kinerja beberapa metode yang disebutkan dalam jawaban untuk sejumlah besar bilangan bulat.

Persiapan

Hanya membuat array 1 juta bilangan bulat acak antara 0 dan 100. Lalu, saya membuat mereka untuk mendapatkan string.

  $integers = array();

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

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

Metode 1

Ini adalah satu kalimat dari jawaban Markus:

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

Metode 2

Ini adalah pendekatan JSON:

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

Metode 3

Saya datang dengan yang ini sebagai modifikasi dari jawaban Markus. Ini masih menggunakan explode()fungsi, tetapi alih-alih memanggil array_map()saya menggunakan foreachloop biasa untuk melakukan pekerjaan untuk menghindari overhead yang array_map()mungkin terjadi. Saya juga parsing dengan (int)vs intval(), tetapi saya mencoba keduanya, dan tidak ada banyak perbedaan dalam hal kinerja.

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

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

Hasil:

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

Intinya adalah rata-rata. Sepertinya metode pertama sedikit lebih lambat untuk 1 juta bilangan bulat, tapi saya tidak melihat peningkatan kinerja 3x dari Metode 2 seperti yang dinyatakan dalam jawaban. Ternyata foreachloop adalah yang tercepat dalam kasus saya. Saya telah melakukan pembandingan dengan Xdebug.

Sunting: Sudah lama sejak jawaban awalnya diposting. Untuk memperjelas, benchmark dilakukan di php 5.6.

MikeWu
sumber
1
Saya benar-benar bertanya-tanya apakah kinerjanya tetap sama di PHP 7, dan bahkan lebih penasaran bagaimana Metode 1 array_map dikombinasikan dengan metode 3 casting dan penutupan / panggilan balik anonim akan melakukan ...
jave.web
array_map(function($v){ return (int)$v; }, $strings_array);inilah yang saya maksud
jave.web
Saya membuat beberapa tes di PHP7.2 menggunakan foreach (metode 1), array_map dengan 'intval' (metode 2) dan array_map dengan fungsi anonim (metode 3) dalam array dengan 10.000.000 elemen. Saya menemukan hasil bahwa metode 2 saya lebih cepat (~ 0,6), kemudian metode 3 (~ 0,75), kemudian metode 1 (~ 1,1)
Gabriel Lima
20

Gunakan kode ini dengan penutup (diperkenalkan pada PHP 5.3), ini sedikit lebih cepat dari jawaban yang diterima dan bagi saya, niat untuk melemparkannya ke integer, lebih jelas:

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

Output akan menjadi:

array(4) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
}
Andreas
sumber
1
Menurut dokumen , ini juga lebih cepat daripada create_function yang diusulkan dalam jawaban lain.
sampai
1
@sampai Ya, Anda benar. Dan create_function sudah tidak digunakan lagi sejak PHP 7.2.0.
Andreas
14

Dalam solusi Mark, Anda akan kembali array([0]=> int 0)jika Anda mencoba mengurai string seperti "test".

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

Tidak yakin apakah ini lebih cepat tetapi membalik array dua kali akan memberikan string numerik ke integer:

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

Metode alternatif yang lebih pendek bisa berupa:

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

Ini memiliki kinerja yang sama dengan Metode 3.

MyGeertRo
sumber
solusi terpendek namun fleksibel bagi saya.
Ryan Arief
5

Jika Anda memiliki array seperti:

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

Dan jika Anda ingin menyamarkannya menjadi bilangan bulat dan tetap berada di dalam array, hal-hal berikut harus dilakukan:

$newArray = array_map( create_function('$value', 'return (int)$value;'),
            $runners);
star18bit
sumber
create_function sudah tidak digunakan lagi sejak PHP 7.2.0. Lebih baik periksa jawaban saya tanpa fungsi create_fungsi, tetapi dengan fungsi anonim.
Andreas
4

Solusi saya adalah casting setiap nilai dengan bantuan fungsi callback:

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

Sederhana saja ...

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

Mengapa Anda mencari cara lain? Looping melakukan pekerjaan tanpa rasa sakit. Jika kinerja menjadi perhatian Anda, Anda dapat melakukannya json_decode (). Orang-orang telah memposting cara menggunakannya, jadi saya tidak memasukkannya di sini.

Catatan: Saat menggunakan operator == alih-alih ===, nilai string Anda secara otomatis dikonversi menjadi angka (mis. Integer atau dobel) jika mereka membentuk angka yang valid tanpa tanda kutip. Sebagai contoh:

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

Dengan demikian, == dapat menyelesaikan masalah Anda, efisien, tetapi akan pecah jika Anda menggunakan === dalam perbandingan.

Devashish Jaiswal
sumber
2

Jika Anda memiliki array multi-dimensi, tidak satu pun dari solusi yang disebutkan sebelumnya akan berfungsi. Ini solusinya:

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

Kemudian, lakukan ini:

arrayValuesToInt($multiDimentionalArray);

Ini akan membuat array seperti ini:

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

terlihat seperti ini:

[[1,2][3,4]

(Ini akan bekerja dengan tingkat kedalaman apa pun)

Skeets
sumber
1

Anda dapat mengonversi nilai dalam array:

<?php

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

Anda juga dapat mengembalikan nilai kembali explodefungsi ke$strings dan beralih bukan menggunakan variabel lain ($ id).

Saya pikir solusi ini adalah cara teraman dengan kinerja terbaik.

Roham Rafii
sumber
1

Gaya PHP 7.4:

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

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

Jenis konversi yang saya gunakan => (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"]'));

Keluaran:

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

Terima kasih

Manoj kumar
sumber