+ toán tử cho mảng trong PHP?


192
$test = array('hi');
$test += array('test','oh');
var_dump($test);

Điều gì có +nghĩa cho mảng trong PHP?


5
Tôi nhận thấy câu hỏi của bạn đã có +=và câu trả lời được chấp nhận +. Từ thử nghiệm của tôi, họ dường như cư xử giống nhau.
dùng151841

7
Các tài liệu tóm tắt nó lên khá tốt
artfulrobot


@RobbieAverill - đây là câu hỏi mà câu hỏi Tham khảo đề cập đến. Vì vậy, nếu bất cứ điều gì mà câu hỏi Tham khảo là trùng lặp
icc97

2
Có ai khác hơi kinh hoàng rằng một điều cơ bản như nối mảng phải được thực hiện thông qua array_merge? Như thể các mảng theo mặc định là mảng kết hợp và mảng số là công dân hạng hai.
icc97

Câu trả lời:


271

Trích dẫn từ Hướng dẫn PHP về Người vận hành Ngôn ngữ

Toán tử + trả về mảng bên phải được gắn vào mảng bên trái; đối với các khóa tồn tại trong cả hai mảng, các phần tử từ mảng bên trái sẽ được sử dụng và các phần tử phù hợp từ mảng bên phải sẽ bị bỏ qua.

Vì vậy, nếu bạn làm

$array1 = ['one',   'two',          'foo' => 'bar'];
$array2 = ['three', 'four', 'five', 'foo' => 'baz']; 

print_r($array1 + $array2);

Bạn sẽ nhận được

Array
(
    [0] => one   // preserved from $array1 (left-hand array)
    [1] => two   // preserved from $array1 (left-hand array)
    [foo] => bar // preserved from $array1 (left-hand array)
    [2] => five  // added from $array2 (right-hand array)
)

Vì vậy, logic của +tương đương với đoạn mã sau:

$union = $array1;

foreach ($array2 as $key => $value) {
    if (false === array_key_exists($key, $union)) {
        $union[$key] = $value;
    }
}

Nếu bạn quan tâm đến các chi tiết của đầu triển khai cấp độ C


Lưu ý, +khác với cách array_merge()kết hợp các mảng:

print_r(array_merge($array1, $array2));

sẽ cung cấp cho bạn

Array
(
    [0] => one   // preserved from $array1
    [1] => two   // preserved from $array1
    [foo] => baz // overwritten from $array2
    [2] => three // appended from $array2
    [3] => four  // appended from $array2
    [4] => five  // appended from $array2
)

Xem các trang được liên kết để biết thêm ví dụ.


1
@Pacerier PHP được sản xuất bởi php.net không có thông số chính thức, nhưng cả +array_mergecuộc gọi zend_hash_mergedưới mui xe. Điều này cũng được mong đợi, vì trong mảng PHP được triển khai dưới dạng bản đồ băm theo thứ tự.
giám mục

1
@Pacerier Các tài liệu trực tuyến php.net là bản ghi gần nhất với một đặc tả, nhưng IMO những tài liệu đó không thua gì một thông số thực: một, chúng được cập nhật sau khi mã được viết; hai, chúng không được viết để bao gồm mọi cách sử dụng đặc biệt.
giám mục

14
Hành vi của PHP +array_mergelà đồi trụy và không trực quan. Chúng ngược lại so với những gì mà một bài đọc tiếng Anh đơn giản sẽ trực giác cho bạn biết các mảng 'thêm' hoặc 'hợp nhất' sẽ làm gì. Các ngôn ngữ / thư viện khác sử dụng +để ghép các danh sách (ví dụ như trong Python) và các hàm "hợp nhất" để thêm các cặp khóa / giá trị từ một đối tượng này sang đối tượng khác (ví dụ như trong lodash). Tuy nhiên, trong PHP thì ngược lại; array_mergecó thể được sử dụng để nối các mảng giống như danh sách nhưng +không thể. Không giống như array_merge, +luôn luôn thực hiện thao tác được gọi là "hợp nhất" trong bất kỳ ngôn ngữ nào khác.
Đánh dấu Amery

1
@ icc97 họ thực sự chỉ là HashMaps. Xem nikic.github.io/2014/12/22/ cường
Gordon

2
Tôi đã thử gửi một lỗi để xem liệu bí danh array_concatcó thể được tạo cho không array_merge.
icc97

18

Ví dụ tốt nhất tôi tìm thấy để sử dụng này là trong một mảng cấu hình.

$user_vars = array("username"=>"John Doe");
$default_vars = array("username"=>"Unknown", "email"=>"no-reply@domain.com");

$config = $user_vars + $default_vars;

Các $default_vars, vì nó gợi ý, là mảng cho các giá trị mặc định. Các $user_varsmảng sẽ ghi đè lên các giá trị quy định tại $default_vars. Bất kỳ giá trị thiếu nào trong $user_varsbây giờ là các giá trị mặc định từ $default_vars.

Điều này sẽ print_rnhư:

Array(2){
    "username" => "John Doe",
    "email" => "no-reply@domain.com"
}

Tôi hi vọng cái này giúp được!


6

Toán tử này lấy liên kết của hai mảng (giống như mảng_merge, ngoại trừ việc có các khóa trùng lặp mảng_merge được ghi đè).

Các tài liệu cho các nhà khai thác mảng được tìm thấy ở đây .


1
Một lời cảnh báo cho người mới bắt đầu ở đây, kết quả của hoạt động là null nếu bất kỳ một trong các mảng là null . Một số có thể không quan tâm đến giả định này vì đây là một hoạt động hợp nhất, kết quả sẽ là mảng thích hợp (không phải null) nếu một trong số chúng là null. Nhưng, điều đó đúng nếu một trong các mảng là một mảng trống .
Sandeepan Nath

Vì vậy, như một thực tiễn tốt, tôi nghĩ, chúng ta nên khởi tạo các mảng đầu vào dưới dạng các mảng trống. Các bạn nói gì?
Sandeepan Nath

5

Cẩn thận với các phím số, nếu chúng nên được bảo quản hoặc nếu bạn không muốn mất bất cứ thứ gì

$a = array(2 => "a2", 4 => "a4", 5 => "a5");
$b = array(1 => "b1", 3 => "b3", 4 => "b4");

liên hiệp

print_r($a+$b);
Array
(
    [2] => a2
    [4] => a4
    [5] => a5
    [1] => b1
    [3] => b3
)

hợp nhất

print_r(array_merge($a, $b));
Array
(
    [0] => a2
    [1] => a4
    [2] => a5
    [3] => b1
    [4] => b3
    [5] => b4
)

3

Các +nhà điều hành sản xuất các kết quả tương tự như array_replace () . Tuy nhiên, vì các đối số toán tử được đảo ngược, thứ tự của mảng kết quả cũng có thể khác nhau.

Mở rộng trên một ví dụ khác từ trang này:

$array1 = array('one', 'two', 'foo' => 'bar');
$array2 = array('three', 'four', 'five', 'foo' => 'baz'); 

print_r($array1 + $array2);
print_r(array_replace($array2, $array1)); //note reversed argument order

đầu ra:

Array
(
    [0] => one   // preserved from $array1
    [1] => two   // preserved from $array1
    [foo] => bar // preserved from $array1
    [2] => five  // added from $array2
)
Array
(
    [0] => one   // preserved from $array1
    [1] => two   // preserved from $array1
    [2] => five  // added from $array2
    [foo] => bar // preserved from $array1
)

Là thứ tự +được đảm bảo bởi thông số kỹ thuật? Thế còn array_replace?
Pacerier 30/03/2015

1
  1. Mảng hoạt động cộng với coi tất cả các mảng là mảng PGS.
  2. Khi xung đột khóa trong khi cộng, giá trị bên trái (trước) sẽ được giữ

Tôi gửi mã dưới đây để làm cho mọi thứ rõ ràng.

$a + $b = array_plus($a, $b)

function array_plus($a, $b){
    $results = array();
    foreach($a as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
    foreach($b as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
    return $results;
}

Việc chạy mã của @ Tamlyn dường như chứng minh rằng yêu cầu của bạn "mảng cộng với hoạt động coi tất cả mảng là mảng PGS" là sai.
Pacerier 30/03/2015

@Pacerier khóa đó cũng có thể là số nguyên.
Hitesh


-4
$var1 = "example";
$var2 = "test";
$output = array_merge((array)$var1,(array)$var2);
print_r($output);

Mảng ([0] => ví dụ [1] => kiểm tra)


1
Chủ đề này đề cập đến một vài lần làm thế nào mảng_merge () KHÔNG đồng dạng.
doublejosh

@doublejosh, "đồng dạng"? Ý nghĩa?
Pacerier 30/03/2015

1
Chúng không giống nhau.
doublejosh
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.