PHP에서 foreach없이 키와 값으로 배열을 내파하는 방법


111

foreach없이 어떻게 이렇게 배열을 돌릴 수 있습니까?

array("item1"=>"object1", "item2"=>"object2",......."item-n"=>"object-n");

이와 같은 문자열에

item1='object1', item2='object2',.... item-n='object-n'

나는 implode()이미 생각 했지만 그것으로 열쇠를 내파하지 않습니다.

foreach가 필요한 경우 foreach를 중첩하지 않을 수 있습니까?

편집 : 문자열을 변경했습니다.


EDIT2 / UPDATE : 이 질문은 꽤 오래 전에 요청되었습니다. 그 당시 저는 모든 것을 한 줄로 작성하고 싶었 기 때문에 삼항 연산자를 사용하고 foreach를 위해 내장 함수 호출을 중첩했습니다. 그것은 좋은 습관이 아니 었습니다! 간결한 지 여부에 관계없이 읽을 수있는 코드를 작성하십시오.

이 경우 : foreach를 함수에 넣는 것은 한 줄로 작성하는 것보다 훨씬 더 읽기 쉽고 모듈화됩니다 (모든 답변이 훌륭하더라도!).


중첩 된 foreach가 necesarry일까요?
하기 Shubham

무엇을 시도하고 있습니까? 왜 그런 제약이 있습니까?
MADARA의 유령

이 내가 짓고 있어요 웹 응용 프로그램 내 데이터베이스 클래스였다가 이미 모두 함께 foreach는의 무리와 함께하고 대한 루프 채워이기 때문에, 내가보기에 지저분한에 그것을 원하지 않아요
tom91136

1
이 선택된 대답은 요청한 방법이지만 데이터베이스를 통해이 정보를 저장하는 경우 json_encode를 사용하는 것이 루프와 이것보다 훨씬 더 우수하다는 점에 유의해야합니다. Exhibit A : willem.stuursma.name/2010/11/22/…
Case

답변:


187

그리고 다른 방법 :

$input = array(
    'item1'  => 'object1',
    'item2'  => 'object2',
    'item-n' => 'object-n'
);

$output = implode(', ', array_map(
    function ($v, $k) {
        if(is_array($v)){
            return $k.'[]='.implode('&'.$k.'[]=', $v);
        }else{
            return $k.'='.$v;
        }
    }, 
    $input, 
    array_keys($input)
));

또는:

$output = implode(', ', array_map(
    function ($v, $k) { return sprintf("%s='%s'", $k, $v); },
    $input,
    array_keys($input)
));

6
이 방법은 작성자가 요청한 방법이지만 데이터베이스를 통해이 정보를 저장하는 경우 json_encode를 사용하는 것이 루프와 이것보다 훨씬 더 우수하다는 점에 유의해야합니다. Exhibit A : willem.stuursma.name/2010/11/22/…
Case

여기에있는 링크가 더 이상 작동하지 않는 것 같습니다. 모두 echo "Hello, World!";해당 함수의 코드 예제를보아야합니까?
Félix Gagnon-Grenier

이 방법은 자신의 요구에 따라 사용자 정의하기가 매우 쉽습니다.
Kabir Hossain 2016

이 방법을 사용하여 선택 옵션을 빌드하고 선택한 옵션을 채웠으며 두 배열이 동일한 크기 여야하므로 두 번째 배열에 대해 이와 같은 작업을 수행 할 수 있습니다. array_fill(0, $input, 'selected-value-you want-to-check-against');이것은 모든 행에 대해 단일 값으로 동일한 크기의 배열을 생성합니다.
krasenslavov

187

다음 과 같이 http_build_query를 사용할 수 있습니다 .

<?php
  $a=array("item1"=>"object1", "item2"=>"object2");
  echo http_build_query($a,'',', ');
?>

산출:

item1=object1, item2=object2 

데모


5
의 다른 매개 변수는 사용하지 않았습니다 http_build_query.
Shiplu Mokaddim

16
+1 지옥 그래 나는 이와 같은 선량의 작은 덩어리를 찾는 것을 좋아합니다 :)
Ben

8
문자열 인코딩에주의하십시오! URL을 작성하지 않는 경우 배열 키 및 값에 원하지 않을 수 있습니다
Matteo

8
당신은 포장 할 수 @Matteo http_build_query에서 urldecode그것을 방지 할 수 있습니다.
Afterlame 2014

3
Genius 솔루션. 그것이 내가 assoc 배열의 디버그 출력에 필요한 전부였습니다.
dixus

33

측정 (100000 회 반복)을 썼는데 연관 배열을 붙이는 가장 빠른 방법은 무엇입니까?

목표 : "key : value, key2 : value2"형식으로 1,000 개 항목의 행을 얻으려면

배열이 있습니다 (예 :) :

$array = [
    'test0' => 344,
    'test1' => 235,
    'test2' => 876,
    ...
];

테스트 번호 1 :

사용 http_build_query않는 str_replace를 :

str_replace('=', ':', http_build_query($array, null, ','));

1000 개 요소를 내파하는 데 걸리는 평균 시간 : 0.00012930955084904

두 번째 테스트 :

사용 array_map내파 :

implode(',', array_map(
        function ($v, $k) {
            return $k.':'.$v;
        },
        $array,
        array_keys($array)
    ));

1000 개 요소를 내파하는 데 걸리는 평균 시간 : 0.0004890081976675

세 번째 테스트 :

사용 array_walk내파 :

array_walk($array,
        function (&$v, $k) {
            $v = $k.':'.$v;
        }
    );
implode(',', $array);

1000 개 요소를 내파하는 데 걸리는 평균 시간 : 0.0003874126245348

네 번째 테스트 :

foreach 사용 :

    $str = '';
    foreach($array as $key=>$item) {
        $str .= $key.':'.$item.',';
    }
    rtrim($str, ',');

1000 개 요소를 내파하는 데 걸리는 평균 시간 : 0.00026632803902445

배열을 붙이는 가장 좋은 방법은 http_build_query 및 str_replace를 사용하는 것입니다.


4
$s = ''; foreach ($array as $k=>$v) { if ($s !== null) { $s .= ','; } $s .= "{$k}:{$v}"; }다른 모든 것을 능가합니다.
Fleshgrinder

1
http_build_query 벤치에는 다른 것과 비교하기 위해 urldecode가 누락되었습니다.
nickl-

다른 옵션 :substr(str_replace('"', '', json_encode($headers)), 1, -1);
nickl- 19 년

1
주의 : 공백이 있으면 값이 변경됩니다. 은 http_build_query플러스 (과 공백을 대체 +) 문자.
Erfun

9

나는 serialize()또는 json_encode().

원하는 정확한 결과 문자열을 제공하지는 않지만 나중에 인코딩 / 저장 / 검색 / 디코딩하는 것이 훨씬 쉽습니다.


3

array_walk 사용

$a = array("item1"=>"object1", "item2"=>"object2","item-n"=>"object-n");
$r=array();
array_walk($a, create_function('$b, $c', 'global $r; $r[]="$c=$b";'));
echo implode(', ', $r);

아이디어


1
나는 array_walk 접근 방식을 좋아하지만 사람들 create_function이 익명 함수를 사용하는 대신 사용 을 제안하는 이유를 이해하지 못합니다 .
Rikki 2014 년

@Rikki 호환성!
Shiplu Mokaddim

아! 나는 그것이 PHP4라는 것을 몰랐습니다!
Rikki 2014 년

@Rikki 아니 . PHP 5.3 이전 버전입니다. 익명 함수 가 PHP 5.3에서 처음 등장
Shiplu Mokaddim 2014 년

그러나 PHP 4.0.1에서 도입되었으므로 PHP4도 마찬가지입니다. 의미론 ... 마이너 버전 업데이트에서 익명 함수만큼 중요한 기능을 추가하는 것은 기이합니다.
Rikki

2

변화

-    return substr($result, (-1 * strlen($glue)));
+    return substr($result, 0, -1 * strlen($glue));

마지막 $ glue없이 전체 문자열을 resive하려면

function key_implode(&$array, $glue) {
    $result = "";
    foreach ($array as $key => $value) {
        $result .= $key . "=" . $value . $glue;
    }
    return substr($result, (-1 * strlen($glue)));
}

그리고 사용법 :

$str = key_implode($yourArray, ",");

나는 이것이 매번 foreach 루프를 작성하는 것에 대한 유효한 대안임을 이해합니다. UPVOTED;)
tony gil

2

디버깅 목적으로. 반복적으로 중첩 된 배열의 배열을 문자열에 씁니다. foreach에 사용됩니다. 함수는 자국어 문자를 저장합니다.

function q($input)
{
    $glue = ', ';
    $function = function ($v, $k) use (&$function, $glue) {
        if (is_array($v)) {
            $arr = [];
            foreach ($v as $key => $value) {
                $arr[] = $function($value, $key);
            }
            $result = "{" . implode($glue, $arr) . "}";
        } else {
            $result = sprintf("%s=\"%s\"", $k, var_export($v, true));
        }
        return $result;
    };
    return implode($glue, array_map($function, $input, array_keys($input))) . "\n";
}

2

PHP의 array_reduce 도 사용할 수 있습니다 .

$a = ['Name' => 'Last Name'];

function acc($acc,$k)use($a){ return $acc .= $k.":".$a[$k].",";}

$imploded = array_reduce(array_keys($a), "acc");

1

배열의 조건이있는 mysql을 만들려면

$sWheres = array('item1'  => 'object1',
                 'item2'  => 'object2',
                 'item3'  => 1,
                 'item4'  => array(4,5),
                 'item5'  => array('object3','object4'));
$sWhere = '';
if(!empty($sWheres)){
    $sWhereConditions = array();
    foreach ($sWheres as $key => $value){
        if(!empty($value)){
            if(is_array($value)){
                $value = array_filter($value); // For remove blank values from array
                if(!empty($value)){
                    array_walk($value, function(&$item){ $item = sprintf("'%s'", $item); }); // For make value string type 'string'
                    $sWhereConditions[] = sprintf("%s in (%s)", $key, implode(', ', $value));
                }
            }else{
                $sWhereConditions[] = sprintf("%s='%s'", $key, $value);
            }
        }
    }
    if(!empty($sWhereConditions)){
        $sWhere .= "(".implode(' AND ', $sWhereConditions).")";
    }
}
echo $sWhere;  // (item1='object1' AND item2='object2' AND item3='1' AND item4 in ('4', '5') AND item5 in ('object3', 'object4'))

1

디버그 출력을 인쇄하는 데 더 일반적으로 알려진 var_exportprint_r 도 있지만 두 함수 모두 선택적 인수를 사용하여 대신 문자열을 반환 할 수 있습니다.

질문의 예를 데이터로 사용합니다.

$array = ["item1"=>"object1", "item2"=>"object2","item-n"=>"object-n"];

print_r배열을 문자열로 바꾸기 위해 사용

이렇게하면 사람이 읽을 수있는 변수 표현이 출력됩니다.

$string = print_r($array, true);
echo $string;

다음을 출력합니다.

Array
(
    [item1] => object1
    [item2] => object2
    [item-n] => object-n
)

var_export배열을 문자열로 바꾸기 위해 사용

변수의 PHP 문자열 표현을 출력합니다.

$string = var_export($array, true);
echo $string;

다음을 출력합니다.

array (
  'item1' => 'object1',
  'item2' => 'object2',
  'item-n' => 'object-n',
)

유효한 PHP이기 때문에 평가할 수 있습니다.

eval('$array2 = ' . var_export($array, true) . ';');
var_dump($array2 === $array);

출력 :

bool(true)

0

다음은 클래스를 사용하는 간단한 예입니다.

$input = array(
    'element1'  => 'value1',
    'element2'  => 'value2',
    'element3' =>  'value3'
);

echo FlatData::flatArray($input,', ', '=');

class FlatData
{

    public static function flatArray(array $input = array(), $separator_elements = ', ', $separator = ': ')
    {
        $output = implode($separator_elements, array_map(
            function ($v, $k, $s) {
                return sprintf("%s{$s}%s", $k, $v);
            },
            $input,
            array_keys($input),
            array_fill(0, count($input), $separator)
        ));
      return $output;
    }

}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.