Làm thế nào để chuyển đổi giá trị mảng từ chuỗi sang int?


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

trả lại

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

Tôi cần các giá trị là kiểu int thay vì kiểu chuỗi. Có cách nào tốt hơn để làm điều này hơn là lặp qua mảng với một foreach và chuyển đổi từng chuỗi thành int?

Câu trả lời:


537

Bạn có thể đạt được điều này bằng cách làm theo mã,

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

3
nhưng nếu bạn có chuỗi 'test', bạn đã có: mảng ([0] => 0)
Dmitry Dubovitsky

10
@Dmitry - đúng vậy .... đó là câu trả lời cho câu hỏi của OP, không hoàn hảo 100% trong mọi trường hợp trả lời cho mọi câu hỏi liên quan tiềm năng. OP có một chuỗi các giá trị số được phân tách bằng dấu phẩy, không phải là phần chọn và trộn văn bản và số
Mark Baker

1
sử dụng mảng_filter ($ mảng, 'is_numeric') tốt hơn, nhưng không thể đúng 100%, vì '0x539', '0b01011' là các giá trị số.
Dmitry Dubovitsky

35
@Dmitry - nếu bạn muốn chỉ trích câu trả lời 18 tháng cho một câu hỏi cụ thể vì nó không hoàn hảo trong mọi tình huống có thể hiểu được và nghĩ rằng bạn có giải pháp tốt hơn, thì hãy thoải mái thêm câu trả lời của riêng bạn cho câu hỏi này, giải thích tại sao câu trả lời của bạn tốt hơn .... không ai ngăn cản bạn ... nhưng hãy để lại câu trả lời này
Mark Baker

intval () ít hiệu suất hơn so với (int) cast. Vì vậy, tốt hơn sử dụng một giải pháp khác với (int). xem Phương pháp 3 tại đây
Fabian Picon

43

Đây là nhanh hơn gấp 3 lần so explode(), array_map()intval():

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

1
@Binod chuỗi của bạn có thể có lỗi cú pháp. Nó nên được định dạng như thế này: $ string = "1,2,3";
sgrodzicki

4
explode () + Array_map () + intval () có thể không nhanh bằng json_decode () nhưng rõ ràng đây không phải là lựa chọn tốt hơn để chọn ... bạn cần xử lý các công cụ khác như lỗi cú pháp json có thể xảy ra khi bạn vệ sinh đầu vào của người dùng
staabm

2
Điều này thật kinh khủng, đặc biệt là khi nó nhanh hơn bản đồ + to_int! php, làm thế nào mà nó có thể đi xa đến thế ...
phoet

3
Đây chỉ là tối ưu hóa vi mô. Không cần phải tối ưu hóa một hoạt động nhỏ như vậy khi truyền một mảng chứa đầy các chuỗi thành số nguyên. Và nếu mảng của bạn chứa rất nhiều phần tử (ví dụ hàng trăm nghìn phần tử), thì có một vấn đề khác, lớn hơn nhiều trong dự án của bạn so với thao tác này.
Andreas

1
@Andreas không giống như vi tối ưu hóa với tôi: blackfire.io/profiles/compare/...
sgrodzicki

41

Vì vậy, tôi đã tò mò về hiệu suất của một số phương pháp được đề cập trong câu trả lời cho số lượng lớn số nguyên.

Sự chuẩn bị

Chỉ cần tạo một mảng gồm 1 triệu số nguyên ngẫu nhiên trong khoảng từ 0 đến 100. Hơn, tôi đã mã hóa chúng để lấy chuỗi.

  $integers = array();

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

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

Phương pháp 1

Đây là một trong những câu trả lời từ câu trả lời của Mark:

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

Phương pháp 2

Đây là cách tiếp cận JSON:

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

Phương pháp 3

Tôi đã đưa ra điều này như là sửa đổi câu trả lời của Mark. Đây vẫn là sử dụng explode()chức năng, nhưng thay vì gọi array_map()tôi đang sử dụng foreachvòng lặp thông thường để thực hiện công việc để tránh chi phí array_map()có thể có. Tôi cũng đang phân tích cú pháp với (int)vs intval(), nhưng tôi đã thử cả hai và không có nhiều khác biệt về hiệu suất.

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

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

Các kết quả:

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

Điểm mấu chốt là trung bình. Có vẻ như phương pháp đầu tiên chậm hơn một chút đối với 1 triệu số nguyên, nhưng tôi không nhận thấy hiệu suất tăng gấp 3 lần của Phương pháp 2 như đã nêu trong câu trả lời. Hóa ra foreachvòng lặp là vòng lặp nhanh nhất trong trường hợp của tôi. Tôi đã thực hiện đo điểm chuẩn với Xdebug.

Chỉnh sửa: Đã được một lúc kể từ khi câu trả lời ban đầu được đăng. Để làm rõ, điểm chuẩn đã được thực hiện trong php 5.6.


1
Tôi thực sự tự hỏi liệu hiệu năng có giữ nguyên trong PHP 7 hay không, và thậm chí còn tò mò hơn nữa, làm thế nào Phương thức 1 mảng_map kết hợp với phương thức truyền 3 và gọi lại / gọi lại ẩn danh sẽ làm gì ...
jave.web

array_map(function($v){ return (int)$v; }, $strings_array);ý tôi là vậy
jave.web

Tôi đã thực hiện một số thử nghiệm trên PHP7.2 bằng cách sử dụng foreach (phương thức 1), mảng_map với 'intval' (phương thức 2) và mảng_map với hàm ẩn danh (phương thức 3) trong một mảng với 10000000 phần tử. Tôi đã đưa ra kết quả rằng phương pháp 2 của tôi nhanh hơn (~ 0,6s), rồi phương pháp 3 (~ 0,75s), rồi phương pháp 1 (~ 1,1s)
Gabriel Lima

20

Sử dụng mã này với một bao đóng (được giới thiệu PHP 5.3), nó nhanh hơn một chút so với câu trả lời được chấp nhận và đối với tôi, ý định chuyển nó thành một số nguyên, rõ ràng hơn:

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

Đầu ra sẽ là:

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

1
Theo tài liệu , điều này cũng nhanh hơn so với created_factor được đề xuất trong các câu trả lời khác.
cho đến

1
@untill Vâng, bạn nói đúng. Và created_function bị phản đối kể từ PHP 7.2.0.
Andreas

14

Trong giải pháp của Mark, bạn sẽ quay lại array([0]=> int 0)nếu bạn cố phân tích một chuỗi, chẳng hạn như "kiểm tra".

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

7

Không chắc chắn nếu điều này nhanh hơn nhưng việc lật mảng hai lần sẽ truyền các chuỗi số thành số nguyên:

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

7

Một phương pháp ngắn hơn có thể là:

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

Nó có hiệu suất tương tự như Phương pháp 3.


giải pháp ngắn nhất nhưng linh hoạt cho tôi.
Ryan Arief

5

Nếu bạn có mảng như:

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

Và nếu bạn muốn chuyển đổi chúng thành số nguyên và giữ trong mảng, sau đây nên thực hiện công việc:

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

create_function bị phản đối kể từ PHP 7.2.0. Tốt hơn hãy kiểm tra câu trả lời của tôi mà không cần tạo_feft, nhưng với chức năng ẩn danh.
Andreas

4

Giải pháp của tôi là truyền từng giá trị với sự trợ giúp của hàm gọi lại:

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

3

Giữ cho nó đơn giản ...

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

Tại sao bạn đang tìm kiếm những cách khác? Looping làm công việc mà không đau. Nếu hiệu suất là mối quan tâm của bạn, bạn có thể đi với json_decode (). Mọi người đã đăng tải cách sử dụng nó, vì vậy tôi không bao gồm nó ở đây.

Lưu ý: Khi sử dụng toán tử == thay vì ===, các giá trị chuỗi của bạn sẽ tự động được chuyển đổi thành số (ví dụ: số nguyên hoặc số kép) nếu chúng tạo thành một số hợp lệ không có dấu ngoặc kép. Ví dụ:

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

Do đó, == có thể giải quyết vấn đề của bạn, hiệu quả, nhưng sẽ bị hỏng nếu bạn sử dụng === trong so sánh.


2

Nếu bạn có một mảng nhiều chiều, không có giải pháp nào được đề cập trước đó sẽ hoạt động. Đây là giải pháp của tôi:

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

Sau đó, chỉ cần làm điều này:

arrayValuesToInt($multiDimentionalArray);

Điều này sẽ tạo ra một mảng như thế này:

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

trông như thế này:

[[1,2][3,4]

(Điều này sẽ làm việc với bất kỳ mức độ sâu)


1

Bạn có thể chuyển đổi các giá trị trong mảng:

<?php

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

Bạn cũng có thể trả về giá trị trả về của explodehàm cho$strings và lặp lại nó thay vì sử dụng một biến khác ($ ids).

Tôi nghĩ giải pháp này là cách an toàn nhất với hiệu suất tốt nhất.


1

Kiểu PHP 7.4:

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

0

Đầu vào => '["3", "6", "16", "120"]'

Chuyển đổi loại tôi đã sử dụng => (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"]'));

Đầu ra:

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

Cảm ơn

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.