2009-04-27 17 views
12

Bối cảnh: Trevor đang làm việc với một thuật toán chuẩn của PHP: lấy một bộ chính tên cặp giá trị mặc định và cập nhật các cặp tên-giá trị đó, nhưng chỉ cho các cặp giá trị tên đó có giá trị cập nhật hợp lệ thực sự tồn tại.php array_merge mà không xóa các giá trị?

Vấn đề: theo mặc định, PHP array_merge hoạt động như thế này ... nó sẽ ghi đè lên giá trị không trống với giá trị trống.

$aamain = Array('firstname'=>'peter','age'=>'32','nation'=>''); 
$update = Array('firstname' => '','lastname' => 'griffin', age =>'33','nation'=>'usa'); 

print_r(array_merge($aamain,$update));  
/* 
Array 
(
    [firstname] =>   // <-- update set this to blank, NOT COOL! 
    [age] => 33    // <-- update set this to 33, thats cool 
    [lastname] => griffin // <-- update added this key-value pair, thats cool 
    [nation] => usa   // <-- update filled in a blank, thats cool. 
) 
*/ 

Câu hỏi: con số thấp nhất-dòng-of-code cách để làm array_merge nơi các giá trị trống không bao giờ ghi đè lên các giá trị đã tồn tại là gì?

print_r(array_coolmerge($aamain,$update));  
/* 
Array 
(
    [firstname] => peter // <-- don't blank out a value if one already exists! 
    [age] => 33 
    [lastname] => griffin 
    [nation] => usa 

) 
*/ 

UPDATE: 2016-06-17T11: 51: 54 câu hỏi đã được cập nhật với bối cảnh làm rõ và đổi tên của các biến.

+1

Bạn muốn điều gì xảy ra với các bản sao? – elzapp

+0

hành vi chuẩn để xử lý các bản sao là tốt: cặp khóa-giá trị trong thanh bên sẽ ghi đè cặp khóa-giá trị tương ứng trong foobar. Sự khác biệt * duy nhất tôi muốn là không bao giờ để cho thanh công cụ xóa một giá trị trong foobar. – dreftymac

+0

** Xem thêm ** (dựa trên python) http://stackoverflow.com/questions/38987/how-to-merge-two-python-dictionaries-in-a-single-expression/39858#39858 – dreftymac

Trả lời

12

Vâng, nếu bạn muốn có một "thông minh" cách để làm điều đó, ở đây nó được, nhưng nó có thể không được đọc như chỉ đơn giản là làm một vòng lặp.

$merged = array_merge(array_filter($foo, 'strval'), array_filter($bar, 'strval')); 

chỉnh sửa: hoặc sử dụng + ...

+0

Cảm ơn vì điều đó. Tránh một vòng lặp có thể được xem như là một "sự thông minh vô dụng" ở một mức độ nào đó - nhưng thật tuyệt khi không phải * luôn luôn * sử dụng vòng lặp khi một cái gì đó như bản đồ, chọn hoặc danh sách hiểu (như được thực hiện trong một số khác ngôn ngữ) có vẻ ngắn gọn hơn. – dreftymac

+3

Sử dụng 'trim' thay vì 'strval' cũng sẽ xóa các mục chỉ chứa khoảng trắng. –

1

Điều này sẽ đặt các bản sao vào một mảng mới, tôi không biết nếu đây là những gì bạn muốn mặc dù.

<?php 
    $foobar = Array('firstname' => 'peter','age' => '33',); 
    $feebar = Array('firstname' => '','lastname' => 'griffin',); 
    $merged=$foobar; 
    foreach($feebar as $k=>$v){ 
    if(isset($foobar[$k]))$merged[$k]=array($v,$foobar[$k]); 
    else $merged[$k]=$v; 
    } 
    print_r($merged); 
?> 

này chỉ đơn giản là sẽ đảm bảo feebar rằng sẽ không bao giờ trống ra một giá trị trong foobar:

<?php 
    $foobar = Array('firstname' => 'peter','age' => '33',); 
    $feebar = Array('firstname' => '','lastname' => 'griffin',); 
    $merged=$foobar; 
    foreach($feebar as $k=>$v) if($v)$merged[$k]=$v; 
    print_r($merged); 
?> 

hoặc ofcourse,

<? 
    function cool_merge($array1,$array2){ 
    $result=$array1; 
    foreach($array2 as $k=>$v) if($v)$result[$k]=$v; 
    return $result; 
    } 

    $foobar = Array('firstname' => 'peter','age' => '33',); 
    $feebar = Array('firstname' => '','lastname' => 'griffin',); 
    print_r(cool_merge($foobar,$feebar)); 
?> 
5

Hãy thử điều này:

$merged = array_map(
    create_function('$foo,$bar','return ($bar?$bar:$foo);'), 
    $foobar,$feebar 
); 

Không phải là giải pháp có thể đọc được hầu hết, nhưng nó phải thay thế chỉ có giá trị không trống, không phân biệt trong đó ra lệnh cho các mảng được thông qua ..

+0

Cảm ơn vì điều đó. – dreftymac

4

Điều chỉnh theo nhu cầu của bạn:

# Replace keys in $foo 
foreach ($foo as $key => $value) { 
    if ($value != '' || !isset($bar[$key])) continue; 
    $foo[$key] = $bar[$key]; 
} 

# Add other keys in $bar 
# Will not overwrite existing keys in $foo 
$foo += $bar; 
+0

Cảm ơn vì điều đó. – dreftymac

1

Nếu bạn cũng muốn giữ lại các giá trị mà là trống ở cả hai mảng:

array_filter($foo) + array_filter($bar) + $foo + $bar 
2
array_replace_recursive($array, $array2); 

Đây là giải pháp.

+2

Khi đoạn mã này có thể giải quyết được câu hỏi, [bao gồm cả giải thích] (http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho người đọc trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn. – JonasCz

+1

Đây là câu trả lời hay nhất ở đây. Cảm ơn! – timothymarois

+0

Tôi đồng ý, đây là giải pháp tốt nhất ở đây. Không cần giải thích. Tài liệu PHP là đủ. – GRowing

Các vấn đề liên quan