배열 값을 문자열에서 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')을 사용하는 것이 좋지만 '0x539', '0b01011'은 숫자 값이므로 100 % true 일 수 없습니다.
Dmitry Dubovitsky

35
@Dmitry-생각할 수있는 모든 상황에서 완벽하지 않기 때문에 특정 질문에 18 개월 된 답변을 비판하고 더 나은 해결책이 있다고 생각하면 자유롭게이 질문에 자신의 답변을 추가하여 설명하십시오. 왜 대답이 더 나은가 .... 아무도 당신을 멈추지 않고 ...하지만이 답변을 그대로 두십시오
Mark Baker

intval ()은 (int) 캐스트 보다 성능 이 떨어 집니다 . 따라서 (int)로 다른 솔루션을 사용하는 것이 좋습니다. 참조 여기 방법 3
파비안 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-syntax error와 같은 다른 것들을 처리해야 할 때 발생할 수 있습니다. 사용자 입력 삭제
staabm

2
이것은 특히 map + to_int보다 빠를 때 끔찍합니다! php, 어떻게 그렇게 왔을 까 ...
phoet

3
이것은 단지 마이크로 최적화입니다. 문자열로 채워진 배열을 정수로 캐스팅하는 등의 작은 작업을 최적화 할 필요가 없습니다. 그리고 배열에 많은 요소 (예 : 수십만 개의 요소)가 포함 된 경우이 작업보다 프로젝트에 더 큰 문제가 있습니다.
Andreas

1
@Andreas 나에게 마이크로 최적화처럼 보이지 않는 : blackfire.io/profiles/compare/...
sgrodzicki

41

그래서 많은 정수에 대한 답변에서 언급 된 일부 방법의 성능에 대해 궁금했습니다.

예비

0에서 100 사이의 1 백만 개의 임의 정수 배열을 만드는 것만으로도 문자열을 얻기 위해 그것들을 내포했습니다.

  $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

나는 Mark의 대답을 수정하여 이것을 생각해 냈습니다. 이것은 여전히 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 백만 정수에 대해 조금 느리게 보이지만 답변에 명시된 방법 2의 3 배 성능 향상을 보지 못했습니다. 그것은 밝혀졌다 foreach루프가 내 경우에는 가장 빠른 하나였다. Xdebug로 벤치마킹을 완료했습니다.

편집 : 답변이 원래 게시 된 지 오래되었습니다. 명확히하기 위해 벤치 마크는 PHP 5.6에서 수행되었습니다.


1
PHP 7에서 성능이 동일하게 유지되는지 궁금합니다. 메소드 1 캐스팅과 클로저 / 익명 콜백과 함께 메소드 1 array_map이 어떻게 작동하는지 궁금합니다.
jave.web

array_map(function($v){ return (int)$v; }, $strings_array);이것이 내가 의미하는 바
jave.web

10000000 요소가있는 배열에서 foreach (방법 1), 'intval'이있는 array_map (방법 2) 및 익명 함수가있는 array_map (방법 3)을 사용하여 PHP7.2에 대한 몇 가지 테스트를 수행했습니다. 내 방법 2가 더 빠름 (~ 0.6 초), 방법 3 (~ 0.75 초), 방법 1 (~ 1.1 초)의 결과를 도출했습니다.
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
doc 에 따르면 , 이것은 다른 답변에서 제안 된 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;
}

다른 변수 ($ ids)를 사용하는 대신 explode함수 의 반환 값을 반환 $strings하고 반복 할 수도 있습니다.

이 솔루션이 최고의 성능을 발휘하는 가장 안전한 방법이라고 생각합니다.


1

PHP 7.4 스타일 :

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

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.