วิธีการแปลงค่าอาร์เรย์จากสตริงเป็น int?


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

ผลตอบแทน

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

ฉันต้องการให้ค่าเป็นประเภท int แทนที่จะเป็นสตริงประเภท มีวิธีที่ดีกว่าในการทำเช่นนี้กว่าวนลูปผ่านอาร์เรย์ด้วย foreach และแปลงแต่ละสายเป็น int?

คำตอบ:


537

คุณสามารถทำได้โดยใช้รหัสต่อไปนี้

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

3
แต่ถ้าคุณมีสตริง 'test' คุณจะได้รับ: array ([0] => 0)
Dmitry Dubovitsky

10
@Dmitry - ถูกต้อง .... มันเป็นคำตอบสำหรับคำถามของ OP ไม่ใช่ 100% ที่สมบูรณ์แบบในทุก ๆ คำตอบของทุกคำถามที่เกี่ยวข้อง OP มีสตริงของค่าตัวเลขคั่นด้วยเครื่องหมายจุลภาคไม่ใช่ตัวเลือกและผสมระหว่างข้อความและตัวเลข
Mark Baker

1
ใช้ array_filter ($ array, 'is_numeric') ดีกว่า แต่มันไม่สามารถเป็นจริงได้ 100% เพราะ '0x539', '0b01011' เป็นค่าตัวเลข
Dmitry Dubovitsky

35
@Dmitry - หากคุณต้องการวิพากษ์วิจารณ์คำตอบอายุ 18 เดือนสำหรับคำถามที่เฉพาะเจาะจงเพราะมันไม่สมบูรณ์แบบในทุกสถานการณ์ที่นึกออกและคิดว่าคุณมีทางออกที่ดีกว่าจากนั้นคุณสามารถเพิ่มคำตอบของคุณเองเพื่ออธิบาย ทำไมคำตอบของคุณถึงดีกว่า .... ไม่มีใครหยุดคุณ ... แต่ทิ้งคำตอบนี้ไว้
Mark Baker

intval () มีประสิทธิภาพน้อยกว่าcast (int) ดังนั้นควรใช้โซลูชันอื่นด้วย (int) ดูวิธีที่ 3 ที่นี่
Fabian Picone

43

นี่คือเกือบ 3 ครั้งเร็วกว่าexplode(), array_map()และintval():

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

1
@Binod สตริงของคุณอาจมีข้อผิดพลาดทางไวยากรณ์ ควรจัดรูปแบบดังนี้: $ string = "1,2,3";
sgrodzicki

4
explode () + array_map () + intval () อาจไม่เร็วเท่า json_decode () แต่เห็นได้ชัดว่าไม่ใช่ตัวเลือกที่ดีกว่าในการเลือก ... คุณต้องจัดการกับสิ่งอื่น ๆ เช่นข้อผิดพลาดไวยากรณ์ json ซึ่งน่าจะเกิดขึ้นเมื่อคุณ ฆ่าเชื้อการป้อนข้อมูลของผู้ใช้
staabm

2
มันน่ากลัวโดยเฉพาะอย่างยิ่งเมื่อมันเร็วกว่าแผนที่ + to_int! PHP, วิธีการที่มันอาจได้มาที่ไกล ...
phoet

3
นี่เป็นเพียงการเพิ่มประสิทธิภาพขนาดเล็ก ไม่จำเป็นต้องปรับแต่งการดำเนินการขนาดเล็กเช่นเดียวกับการหล่ออาร์เรย์ที่เต็มไปด้วยสตริงเป็นจำนวนเต็ม และถ้าอาเรย์ของคุณมีองค์ประกอบมากมาย (เช่นองค์ประกอบนับแสน) ก็มีอีกปัญหาหนึ่งที่ใหญ่กว่าโครงการของคุณมากกว่าการดำเนินการนี้
Andreas

1
@Andreas ดูไม่เหมือนการเพิ่มประสิทธิภาพแบบ micro สำหรับฉัน: blackfire.io/profiles/compare/…
sgrodzicki

41

ดังนั้นฉันอยากรู้เกี่ยวกับประสิทธิภาพของวิธีการบางอย่างที่กล่าวถึงในคำตอบสำหรับจำนวนเต็มจำนวนมาก

การจัดเตรียม

เพียงแค่สร้างอาร์เรย์ของจำนวนเต็ม 1 ล้านสุ่มระหว่าง 0 และ 100 กว่าฉันได้กำหนดให้พวกเขาได้รับสตริง

  $integers = array();

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

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

วิธีที่ 1

นี่คือหนึ่งซับจากคำตอบของ Mark:

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

วิธีที่ 2

นี่คือวิธีการ JSON:

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

วิธีที่ 3

ฉันมากับอันนี้เป็นการดัดแปลงคำตอบของมาร์ค นี้ยังคงใช้explode()ฟังก์ชั่น แต่แทนที่จะเรียกarray_map()ผมใช้ประจำforeachวงที่จะทำงานเพื่อหลีกเลี่ยงค่าใช้จ่ายarray_map()อาจจะมี ฉันกำลังวิเคราะห์ด้วย(int)vs intval()แต่ฉันลองทั้งสองอย่างและไม่มีความแตกต่างในแง่ของประสิทธิภาพ

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

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

ผล:

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

บรรทัดล่างคือค่าเฉลี่ย ดูเหมือนว่าวิธีแรกจะช้ากว่าเล็กน้อยสำหรับ 1 ล้านจำนวนเต็ม แต่ฉันไม่ได้สังเกตเห็นการเพิ่มขึ้นของประสิทธิภาพที่ 3 ของวิธีที่ 2 ตามที่ระบุไว้ในคำตอบ มันกลับกลายforeachเป็นห่วงที่เร็วที่สุดในกรณีของฉัน ฉันทำการเปรียบเทียบกับ Xdebug แล้ว

แก้ไข: ไม่นานมานี้ตั้งแต่คำตอบถูกโพสต์ไว้ เพื่อชี้แจงมาตรฐานเสร็จใน php 5.6


1
ฉันสงสัยจริง ๆ ว่าประสิทธิภาพการทำงานยังคงเหมือนเดิมใน PHP 7 และยิ่งอยากรู้อยากเห็นมากขึ้นวิธีที่ 1 array_map รวมกับวิธีที่ 3 การหล่อและการปิด / โทรกลับไม่ระบุชื่อจะทำ ...
jave.web

array_map(function($v){ return (int)$v; }, $strings_array);นี่คือสิ่งที่ฉันหมายถึง
jave.web

ฉันทำการทดสอบบางอย่างเกี่ยวกับ PHP7.2 โดยใช้ foreach (วิธีที่ 1), array_map ด้วย 'intval' (วิธีที่ 2) และ array_map พร้อมฟังก์ชันที่ไม่ระบุตัวตน (วิธีที่ 3) ในอาร์เรย์ที่มีองค์ประกอบ 10,000,000 รายการ ฉันพบผลลัพธ์ที่วิธีการที่ 2 ของฉันเร็วขึ้น (~ 0.6s), จากนั้นวิธีที่ 3 (~ 0.75s), จากนั้นวิธีที่ 1 (~ 1.1s)
Gabriel Lima

20

ใช้รหัสนี้ด้วยการปิด (แนะนำในPHP 5.3) มันเร็วกว่าคำตอบที่ยอมรับเล็กน้อยและสำหรับฉันความตั้งใจที่จะแปลงให้เป็นจำนวนเต็มนั้นชัดเจนขึ้น:

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

ผลลัพธ์จะเป็น:

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

1
ตามเอกสารนี้ยังเร็วกว่า create_function ที่เสนอในคำตอบอื่น ๆ
จนถึง

1
@ จนถึงใช่คุณพูดถูก และ create_function นั้นเลิกใช้แล้วตั้งแต่ PHP 7.2.0
Andreas

14

ในโซลูชันของ Mark คุณจะส่งคืนarray([0]=> int 0)ถ้าคุณพยายามวิเคราะห์สตริงเช่น "test"

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

7

ไม่แน่ใจว่าจะเร็วกว่านี้หรือไม่ แต่การโยนอาร์เรย์สองครั้งจะส่งสตริงตัวเลขไปที่จำนวนเต็ม:

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

7

วิธีที่สั้นกว่าทางเลือกอาจเป็น:

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

มันมีประสิทธิภาพเช่นเดียวกับวิธีที่ 3


ทางออกที่สั้นที่สุดและยืดหยุ่นสำหรับฉัน
Ryan Arief

5

หากคุณมีอาร์เรย์เช่น:

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

และถ้าคุณต้องการที่จะแปลงเป็นจำนวนเต็มและเก็บไว้ในอาร์เรย์ต่อไปนี้ควรทำงาน:

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

create_function เลิกใช้แล้วตั้งแต่ PHP 7.2.0 ตรวจสอบคำตอบของฉันได้ดีกว่าโดยไม่มี create_function แต่มีฟังก์ชันที่ไม่ระบุชื่อ
Andreas

4

โซลูชันของฉันหล่อแต่ละค่าด้วยความช่วยเหลือของฟังก์ชันเรียกกลับ:

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

3

ง่าย ๆ เข้าไว้...

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

ทำไมคุณมองหาวิธีอื่น การวนรอบทำได้โดยปราศจากความเจ็บปวด หากประสิทธิภาพเป็นสิ่งที่คุณกังวลคุณสามารถไปกับjson_decode ()มันได้ ผู้คนโพสต์วิธีใช้สิ่งนั้นดังนั้นฉันไม่ได้รวมไว้ที่นี่

หมายเหตุ:เมื่อใช้ตัวดำเนินการ == แทน === ค่าสตริงของคุณจะถูกแปลงเป็นตัวเลขโดยอัตโนมัติ (เช่นจำนวนเต็มหรือสองเท่า) หากพวกเขาสร้างตัวเลขที่ถูกต้องโดยไม่มีเครื่องหมายอัญประกาศ ตัวอย่างเช่น:

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

ดังนั้น == อาจแก้ปัญหาของคุณได้อย่างมีประสิทธิภาพ แต่จะแตกถ้าคุณใช้ === ในการเปรียบเทียบ


2

หากคุณมีอาเรย์หลายมิติจะไม่มีวิธีแก้ไขปัญหาที่กล่าวถึงก่อนหน้านี้ทำงาน นี่คือทางออกของฉัน:

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

จากนั้นให้ทำดังนี้

arrayValuesToInt($multiDimentionalArray);

สิ่งนี้จะทำให้อาร์เรย์เป็นเช่นนี้:

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

มีลักษณะเช่นนี้:

[[1,2][3,4]

(สิ่งนี้จะใช้ได้กับทุกระดับความลึก)


1

คุณสามารถแปลงค่าในอาเรย์:

<?php

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

คุณยังสามารถส่งคืนค่าส่งคืนของexplodeฟังก์ชันได้$stringsและทำซ้ำได้แทนที่จะใช้ตัวแปรอื่น ($ ids)

ฉันคิดว่าวิธีนี้เป็นวิธีที่ปลอดภัยที่สุดด้วยประสิทธิภาพที่ดีที่สุด



0

อินพุต => '["3", "6", "16", "120"]'

การแปลงประเภทที่ฉันใช้ => (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"]'));

เอาท์พุท:

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

ขอบคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.