PHP는 하나의 배열을 다른 배열에 추가합니다 (array_push 또는 + 아님)


278

키를 비교하지 않고 한 배열을 다른 배열에 추가하는 방법은 무엇입니까?

$a = array( 'a', 'b' );
$b = array( 'c', 'd' );

말은해야한다 : Array( [0]=>a [1]=>b [2]=>c [3]=>d ) 내가 좋아하는 뭔가를 사용하는 경우 []또는 array_push, 그 결과 중 하나가 발생합니다 :

Array( [0]=>a [1]=>b [2]=>Array( [0]=>c [1]=>d ) )
//or
Array( [0]=>c [1]=>d )

이것은 무언가를해야하지만보다 우아한 방식으로해야합니다.

foreach ( $b AS $var )
    $a[] = $var;

16
array_merge ($a, $b)적어도 PHP 5 이상으로 원하는 것을 정확하게 수행해야합니다.
tloach


6
출력 중 어느 것도 당신이에서 올 게시 된 array_merge();출력의 array_merge();당신이 필요 exaclty해야한다 :print_r(array_merge($a,$b)); // outputs => Array ( [0] => a [1] => b [2] => c [3] => d )
ACM

2
나는 "추가"라는 용어에 전적으로 동의하지 않습니다. 추가는 실제로 한 배열의 항목이 이미 일부 요소가있을 수있는 다른 (대상) 배열의 요소가되어 대상 배열을 변경 함을 의미합니다. 병합은 새 배열과 두 배열의 COPIES 요소를 할당하지만 추가는 실제로 추가 메모리 할당없이 대상 배열 요소를 재사용하는 것을 의미합니다.
tishma

답변:


424

array_merge 우아한 방법입니다 :

$a = array('a', 'b');
$b = array('c', 'd');
$merge = array_merge($a, $b); 
// $merge is now equals to array('a','b','c','d');

같은 일을 :

$merge = $a + $b;
// $merge now equals array('a','b')

+연산자가 실제로 병합하지 않기 때문에 작동하지 않습니다. 그들이 경우 $a와 동일한 키를 가지고 $b, 그것은 아무것도하지 않습니다.


16
키가 숫자가 아니라 문자열 인 경우주의하십시오. 문서에서 : 입력 배열에 동일한 문자열 키가있는 경우 해당 키의 이후 값이 이전 키를 덮어 씁니다
Dusan Plavak

또는 @bstoney 답변으로 현대식 splat 연산자를 사용하십시오 stackoverflow.com/a/37065301/962634
basil

76

PHP 5.6+에서이를 수행하는 또 다른 방법은 ...토큰 을 사용하는 것입니다

$a = array('a', 'b');
$b = array('c', 'd');

array_push($a, ...$b);

// $a is now equals to array('a','b','c','d');

이것은 또한 Traversable

$a = array('a', 'b');
$b = new ArrayIterator(array('c', 'd'));

array_push($a, ...$b);

// $a is now equals to array('a','b','c','d');

경고 하지만 :

  • 7.3 이전의 PHP 버전에서는 $b배열이 비어 있거나 빈 배열 일 경우 치명적 오류가 발생합니다
  • PHP 7.3에서는 $b통과 할 수 없는 경우 경고가 발생합니다

그러한 구문에 사용되는 용어는 무엇입니까? (예를 들어 JS에서는 스프레드 연산자라고합니다) 아니면 문서에 대한 링크를 제공 할 수 있습니까?
바질

3
@basil 당신은 ...일반적으로 splat operatorPHP에서 이라고합니다 .
mickmackusa

이전 요소를 재정의하지 않고 배열을 자체에 추가하는 간단한 방법을 찾을 때 가장 유용한 대답입니다.
다니엘 Böttner

1
array_pushPHP 7.3부터 단일 인수를 허용하므로 빈 배열의 오류를 방지합니다.
vctls

실제로 이것은 가장 우아하고 효율적인 방법입니다. 감사
하산 알리 살렘

33

왜 사용하지

$appended = array_merge($a,$b); 

올바른 내장 방법을 사용하고 싶지 않습니까?


OP는 array_merge ()를 "사용하고 싶지 않다"고 어디에서 말합니까?
KittenCodings

3
@KittenCodings-질문의 "편집 기록"을 읽으십시오. 원래 질문의 제목은 PHP append one array to another (not array_merge or array_push)... PHP append one array to another (not array_merge or +)현재 제목으로 변경하기 전에 다음에 수정되었습니다
Mark Baker

2
@MarkBaker 와우! 나는 편집 기록이 있다는 것을 몰랐다! 죄송합니다. 이로 인해 변경 사항이 많고 중재자가 단어를 사람들의 입에 넣지 못하게 막았습니다. 이전에는 일부 질문이 지워지고 내용이 삭제 / 편집 된 댓글이 무효화되었다고 느꼈습니다. 편집 기록, 나는 지금부터 도대체 확실하게
KittenCodings

21

꽤 오래된 게시물이지만 한 배열을 다른 배열에 추가하는 방법을 추가하고 싶습니다.

만약

  • 하나 또는 두 배열 모두에 연관 키가 있습니다
  • 두 배열의 키는 중요하지 않습니다

다음과 같은 배열 함수를 사용할 수 있습니다.

array_merge(array_values($array), array_values($appendArray));

array_merge는 숫자 키를 병합하지 않으므로 $ appendArray의 모든 값을 추가합니다. foreach-loop 대신 native php 함수를 사용하는 동안 많은 요소를 가진 배열에서 더 빠릅니다.

추가 2019-12-13 : PHP 7.4부터는 Array Spread Operator 방식으로 배열을 추가하거나 추가 할 수 있습니다.

    $a = [3, 4];
    $b = [1, 2, ...$a];

이전과 마찬가지로이 새로운 기능에서 키가 문제가 될 수 있습니다.

    $a = ['a' => 3, 'b' => 4];
    $b = ['c' => 1, 'a' => 2, ...$a];

"치명적인 오류 : 발견되지 않은 오류 : 문자열 키로 배열의 압축을 풀 수 없습니다"

    $a = [3 => 3, 4 => 4];
    $b = [1 => 1, 4 => 2, ...$a];

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

    $a = [1 => 1, 2 => 2];
    $b = [...$a, 3 => 3, 1 => 4];

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


1
이것은 또한 입력 배열을 그대로 두는 이점이 있습니다.
Jon Surrell

1
예, array_values를 추출하여 동일한 키로 병합하지 않도록하는 것이 더 안전합니다.
Gabriel Rodriguez

15
<?php
// Example 1 [Merging associative arrays. When two or more arrays have same key
// then the last array key value overrides the others one]

$array1 = array("a" => "JAVA", "b" => "ASP");
$array2 = array("c" => "C", "b" => "PHP");
echo " <br> Example 1 Output: <br>";
print_r(array_merge($array1,$array2));

// Example 2 [When you want to merge arrays having integer keys and
//want to reset integer keys to start from 0 then use array_merge() function]

$array3 =array(5 => "CSS",6 => "CSS3");
$array4 =array(8 => "JAVASCRIPT",9 => "HTML");
echo " <br> Example 2 Output: <br>";
print_r(array_merge($array3,$array4));

// Example 3 [When you want to merge arrays having integer keys and
// want to retain integer keys as it is then use PLUS (+) operator to merge arrays]

$array5 =array(5 => "CSS",6 => "CSS3");
$array6 =array(8 => "JAVASCRIPT",9 => "HTML");
echo " <br> Example 3 Output: <br>";
print_r($array5+$array6);

// Example 4 [When single array pass to array_merge having integer keys
// then the array return by array_merge have integer keys starting from 0]

$array7 =array(3 => "CSS",4 => "CSS3");
echo " <br> Example 4 Output: <br>";
print_r(array_merge($array7));
?>

산출:

Example 1 Output:
Array
(
[a] => JAVA
[b] => PHP
[c] => C
)

Example 2 Output:
Array
(
[0] => CSS
[1] => CSS3
[2] => JAVASCRIPT
[3] => HTML
)

Example 3 Output:
Array
(
[5] => CSS
[6] => CSS3
[8] => JAVASCRIPT
[9] => HTML
)

Example 4 Output:
Array
(
[0] => CSS
[1] => CSS3
)

참조 소스 코드


12

큰 배열의 경우 메모리 복사를 피하기 위해 array_merge없이 연결하는 것이 좋습니다.

$array1 = array_fill(0,50000,'aa');
$array2 = array_fill(0,100,'bb');

// Test 1 (array_merge)
$start = microtime(true);
$r1 = array_merge($array1, $array2);
echo sprintf("Test 1: %.06f\n", microtime(true) - $start);

// Test2 (avoid copy)
$start = microtime(true);
foreach ($array2 as $v) {
    $array1[] = $v;
}
echo sprintf("Test 2: %.06f\n", microtime(true) - $start);


// Test 1: 0.004963
// Test 2: 0.000038

매력처럼 작동합니다.이 방법은 50 배 빠릅니다.
luttkens

9

bstoney와 Snark의 답변에서 나는 다양한 방법에 대해 몇 가지 테스트를 수행했습니다.

// Test 1 (array_merge)
$array1 = $array2 = array_fill(0, 50000, 'aa');
$start = microtime(true);
$array1 = array_merge($array1, $array2);
echo sprintf("Test 1: %.06f\n", microtime(true) - $start);

// Test2 (foreach)
$array1 = $array2 = array_fill(0, 50000, 'aa');
$start = microtime(true);
foreach ($array2 as $v) {
    $array1[] = $v;
}
echo sprintf("Test 2: %.06f\n", microtime(true) - $start);

// Test 3 (... token)
// PHP 5.6+ and produces error if $array2 is empty
$array1 = $array2 = array_fill(0, 50000, 'aa');
$start = microtime(true);
array_push($array1, ...$array2);
echo sprintf("Test 3: %.06f\n", microtime(true) - $start);

어느 생산 :

Test 1: 0.002717 
Test 2: 0.006922 
Test 3: 0.004744

ORIGINAL : PHP 7부터 방법 3은 foreach 루프가 작동 하는 방식으로 인해 훨씬 ​​더 나은 대안이라고 생각합니다 . 이는 반복되는 배열의 사본을 만드는 것입니다.

방법 3이 질문에서 'not array_push'의 기준에 대한 대답은 아니지만 한 줄이며 모든면에서 가장 높은 성능이지만 질문은 ... 구문이 옵션이라고 생각했습니다.

업데이트 25/03/2020 : 변수가 재설정되지 않아 결함이있는 테스트를 업데이트했습니다. 흥미롭게도 (또는 혼란스럽게도) 결과는 테스트 1이 가장 빠르며 가장 느린 위치에서 0.008392에서 0.002717로 떨어졌습니다! 이것은 테스트 결함의 영향을받지 않았기 때문에 PHP 업데이트 만 가능합니다.

그래서, saga는 계속됩니다. 나는 지금부터 array_merge를 사용할 것입니다!


2
각 테스트 전에 array1을 재설정하지 않으므로 각 테스트에는 이전보다 50,000 개 이상의 항목이 있습니다.
Dakusan

몇 년이 지난 후에도 당신이 처음으로 나를 데리러 오게 된 것은 놀라운 일입니다. 감사합니다. 곧 재시험을 할 것입니다 :)
Jamie Robinson

5

PHP 7.4부터 ... 연산자를 사용할 수 있습니다 . 루비를 포함한 다른 언어에서는 스 플랫 연산자 라고도합니다 .

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
var_dump($fruits);

산출

array(5) {
    [0]=>
    string(6) "banana"
    [1]=>
    string(6) "orange"
    [2]=>
    string(5) "apple"
    [3]=>
    string(4) "pear"
    [4]=>
    string(10) "watermelon"
}

Splat 연산자array_merge 보다 나은 성능을 가져야합니다 . 이는 splat 연산자가 언어 구조이고 array_merge가 함수일뿐만 아니라 상수 배열에 대해 컴파일 시간 최적화가 수행 될 수 있기 때문입니다.

또한 splat 연산자 전후에 일반 요소를 추가 할 수 있으므로 배열의 모든 위치에서 splat 연산자 구문을 사용할 수 있습니다.

$arr1 = [1, 2, 3];
$arr2 = [4, 5, 6];
$arr3 = [...$arr1, ...$arr2];
$arr4 = [...$arr1, ...$arr3, 7, 8, 9];

3

PHP7 이전에는 다음을 사용할 수 있습니다.

array_splice($a, count($a), 0, $b);

array_splice()배열 (첫 번째 인수)을 참조하여 작동하고 두 번째 인수에서 시작한 값 목록과 세 번째 인수 수 대신 배열 (4 번째 인수) 값을 넣습니다. 두 번째 인수를 소스 배열의 끝으로 설정하고 세 번째 인수를 0으로 설정하면 첫 번째 인수에 네 번째 인수 값을 추가합니다


비 이동 접합 마법을 따르지 않는 사람들에게 설명을 포함시켜야합니다.
mickmackusa

0

빈 배열을 기존의 새 값과 병합하려는 경우. 먼저 초기화해야합니다.

$products = array();
//just example
for($brand_id=1;$brand_id<=3;$brand_id++){
  array_merge($products,getByBrand($brand_id));
}
// it will create empty array
print_r($a);

//check if array of products is empty
for($brand_id=1;$brand_id<=3;$brand_id++){
  if(empty($products)){
    $products = getByBrand($brand_id);
  }else{
    array_merge($products,getByBrand($brand_id));
  }
}
// it will create array of products

도움을 바랍니다.


0

foreach 루프는 array_merge보다 빠르므로 기존 배열에 값을 추가하기 때문에 다른 배열의 끝에 배열을 추가하려면 대신 루프를 선택하십시오.

// Create an array of arrays
$chars = [];
for ($i = 0; $i < 15000; $i++) {
    $chars[] = array_fill(0, 10, 'a');
}

// test array_merge
$new = [];
$start = microtime(TRUE);
foreach ($chars as $splitArray) {
    $new = array_merge($new, $splitArray);
}
echo microtime(true) - $start; // => 14.61776 sec

// test foreach
$new = [];
$start = microtime(TRUE);
foreach ($chars as $splitArray) {
    foreach ($splitArray as $value) {
        $new[] = $value;
    }
}
echo microtime(true) - $start; // => 0.00900101 sec
// ==> 1600 times faster

이 답변은 페이지에 새로운 정보를 제공하지 않습니다. 성능 비교는 몇 년 전에 게시되었습니다.
mickmackusa 2016 년

-4

이건 어때요:

$appended = $a + $b;

1
내가 말한 것처럼 키를 비교하고 결과는 다음과 같습니다. Array ([0] => a [1] => b)
Danil K

1
당신이 있습니까 장해야 이 키를 비교합니다? 문서 (강조 광산)에 다음과 같이 말합니다. "입력 배열에 동일한 문자열 키가있는 경우 해당 키의 이후 값이 이전 키를 덮어 씁니다. 그러나 배열에 숫자 키가 포함 된 경우 이후 값은 원본을 덮어 쓰지 않습니다 가치, 그러나 추가 될 것입니다. ". 실제로 키가 아닌 '0' => 'a'... 확실하지 0 => 'a'않습니까?
Piskvor 건물 왼쪽

@Piskvor는 키에 대해 '0'과 0 사이에 차이가 없습니다.
고든

고든이 맞아 정수 키가 아닌 숫자 키를 강조 합니다 .
netcoder

1
@ Gordon : 아, 맞아-그것이 두 가지를 한 번에 생각할 때 얻는 것입니다. php.net/manual/en/language.operators.array.php는 대한 설명서입니다array + array
Piskvor 건물 왼쪽
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.