2016-07-08 9 views
2

簡単に言うと、2つの単純な配列があり、2番目の配列の特定のキーが空の値を持っているかどうかを確認し、最初の配列の対応する値で置き換えます。PHP多次元配列の特定の要素を比較して変更する

例:

$a1 = [ 1 => 'one', 2 => 'two', 3 => 'three',5=>'cinco', 6=>'six']; 
$a2 = [ 2 => 'two', 5=>'five', 6=>'' ]; 

結果:

Array 
(
    [2] => two 
    [5] => five 
    [6] => six 
) 

次のコードは、このために、すでに動作します。

$keys = array_keys($a1); 
foreach ($keys as $k) 
{ 
    if ((isset($a2[$k])) && (($a2[$k]) == '')) { 
    $a2[$k] = $a1[$k]; 
    } 
} 
print_r($a2); 

しかし、これを2つの2次元配列に適用する場合はどうなりますか?その場合、適切なアプローチは何でしょうか?のは、これら2つの2Dの配列がなるとしましょう:

$superheroes_complete = array(
    "spiderman" => array(
     "name" => "Peter Parker", 
     "email" => "[email protected]", 
    ), 
    "superman" => array(
     "name" => "Clark Kent", 
     "email" => "[email protected]", 
    ), 
    "ironman" => array(
     "name" => "Harry Potter", 
     "email" => "[email protected]", 
    ) 
); 

$superheroes_empty = array(
    "spiderman" => array(
     "name" => "Peter Parker", 
     "email" => "", 
    ), 
    "superman" => array(
     "name" => "Clark Kent", 
     "email" => "something", 
    ), 
    "ironman" => array(
     "name" => "Harry Potter", 
     "email" => "another one", 
    ) 
); 

期待:

$superheroes = array(
    "spider-man" => array(
     "name" => "Peter Parker", 
     "email" => "[email protected]", 
    ), 
    "super-man" => array(
     "name" => "Clark Kent", 
     "email" => "something", 
    ), 
    "iron-man" => array(
     "name" => "Harry Potter", 
     "email" => "another one", 
    ) 
); 

多くの感謝と、事前にあなたに感謝!

+0

ループ用にネストされました – ebyt

答えて

1

あなたは自分が第二foreachループと同様のチェックに別のレベルを追加することができますので、あなたは、あなたのデータに別のレベルを追加しました:あなただけの「電子メールの世話をする必要がある場合は

foreach ($superheroes_complete as $hero => $info) { 
    foreach ($info as $key => $value) { 
     if (empty($superheroes_empty[$hero][$key])) { 
      $superheroes_empty[$hero][$key] = $value; 
     } 
    } 
} 
+0

ありがとうございました!完璧に動作します。 – Alberto

+0

ようこそ。 –

+0

しかし、シンプルな配列と2D配列を持つ状況があればどうでしょうか? シンプルな配列: $ superheroes_complete = array(1 => 'one'、2 => 'two'、3 => 'three'、5 => 'cinco'、6 => 'six'、 'email '=> '[email protected]'); ' 2D配列: ' $のsuperheroes_empty =配列( "スパイダーマン" =>配列( "名" => "ピーター・パーカー"、 "電子メール" = > ""、 )、 "スーパーマン" =>配列( "名" => "クラーク・ケント"、 "電子メール" => "何か"、 )、 "アイアンマン" =>配列( 「名"=>" Harry Potter "、 " email "=>" another one "、 ) ); ' – Alberto

0

「フィールドあなたはこれを行うことができます。

<?php 
$keys = array_keys($superheroes_complete); 
foreach ($keys as $k) 
{ 
    if ((isset($superheroes_empty[$k]["email"])) && 
     (($superheroes_empty[$k]["email"]) == '')) { 
    $superheroes_empty[$k]["email"] = $superheroes_complete[$k]["email"]; 
    } 
} 
var_dump($superheroes_empty); 
?> 
+1

ありがとうございました!これも機能します。 – Alberto

1

あなた1Dのケースを簡素化することができることをまずノート:

foreach ($a2 as $k => $v) { 
    if (!isset($v)) { 
    $a2[$k] = $a1[$k]; 
    } 
} 
第一レベルのキーが常に同じと仮定2Dの場合のその後

、(またはそれは全く異なる問題になります!):ネストの深さは無制限で、一般的なケースでは

foreach ($superheroes_complete as $main_k => $main_v) { 
    foreach ($main_v as $k => $v) { 
    if (!isset($v)) { 
     $superheroes_empty[$main_k][$k] = $superheroes_complete[$main_k][$k]; 
    } 
    } 
0

、あなたが使用することができますこの再帰関数:

function fillEmpty(&$filled, &$empty) { // arguments are by reference 
    if ($empty === "") { 
     $empty = $filled; 
     return; 
    } 
    if (!is_array($filled) || !is_array($empty)) return; 
    foreach ($filled as $key => $value) { 
     if (isset($empty[$key])) fillEmpty($value, $empty[$key]); 
    } 
} 

例コール:

fillEmpty($superheroes_complete, $superheroes_empty); 

これは、空の値を充填し、二番目の引数を変更します。それはそれはあなたの幸運な日であるかもしれないeval.in

0

上で実行

を参照してください、PHPは、いくつかは、配列の値とキーを比較する機能が組み込まれています。 array_diff()を使用すると、2つ以上の配列を比較してその差を返すことができます。あなたはまた、逆を行うarray_intersect()を使用することができます。

キーのみを比較する場合は、キーの違いのみを返すarray_diff_key()を使用します。一致するキーを返すのはarray_intersect_key()です。

+0

'array_'関数だけを使って解決策を見てみたいと思います。そのコードがなければ、これはコメントであり、答えはそれです。 – Pevara

0

また、再帰的解決策を検討することもできます。これは、1Dおよび2D配列、またはN次元の配列でも機能します。

再帰は、リソースを大量に消費する可能性があるため、注意して使用する必要があります。しかし、これはもっと汎用的な解決策であり、コード構造体の入れ子構造が小さく、早期のリターンでコードをきれいに保つことができます。私はネイティブのarray_walkメソッドを使用します。なぜなら、PHPループがうまくいくはずだと教えられたからです。

だからこれは私のコードは次のようになります。あなたはそれは両方のあなたの例に動作することを確認できるように、私は少しデモを設定した

function array_complement_recursive(&$partial, $complete) { 
    array_walk($partial, function(&$value, $key) use ($complete) { 
     // (for safety) complete does not contain matching key: done 
     if (! array_key_exists($key, $complete)) { 
      return; 
     } 

     // value is array: call recursive 
     if (is_array($value)) { 
      array_complement_recursive($value, $complete[$key]); 
      return; 
     } 

     // value is not 'empty': done 
     // note that null, 0, false will also not match, you may want to make 
     // this check more specific to match only the empty string 
     if ($value) { 
      return; 
     } 

     $value = $complete[$key]; 
    }); 
} 

。そして私が言ったように、それはより多くの次元、またはより不規則な構造を持つ配列に対しても機能するはずです。

http://phpfiddle.org/main/code/49iz-vrwg

私が説明するためにいくつかのコメントを追加しましたが、何かが不明である場合はお気軽にしました。

関連する問題