2017-12-18 6 views
4

データの下に2つの配列がある -
$ a =配列(a、b、d、c、e、a);
$ b =配列(a、a、d、e、c、a);ペアを構成する配列要素をアンセット/削除するPHP

配列値をペアとして削除したい、つまり、配列 'a'と配列 'b'に存在する必要があります。 わかっていれば、同様のペアを形成する要素を削除したいと思います。

出力は最終的には $a = [b]; $b = [a];のようになりますが、これは左に残っているペアではないためです。

私はarray_diffを使用してみましたが、それは私に期待される出力を取得していない -

$arr1 = array_diff($aArr, $bArr); 
$arr2 = array_diff($bArr, $aArr); 

print_r($arr1); 
print "<br>"; 
print_r($arr2); 

$res = count($arr1) + count($arr2); 
print $res; 

入力が
アレイ(C、D、E)
アレイ(Aの場合、このコードは、正常に動作していますA、B、C)

しかし
アレイ(A、B、D、E、C、A)
アレイ(B、A、B、D、E、Cなどの入力のためにゼロを与えます、a)

どうすればこの問題を解決できますか?おかげさまで

+0

は絶対位置?同様に、$ aに10個の要素がある場合、$ bにも10があり、$ a [9]は$ b [9]に対してチェックされますか? – Forbs

+0

@Forbs、ええと、aとbのサイズは絶対的です。$ aと$ bは同じ要素数を持ちます。 –

+0

これはコード面接の質問のように感じます。 lol – paulz

答えて

3

あなたは、参照によりarray_filterとパッシングを使用することができます。ここでは

$a = ['a', 'b', 'd', 'c', 'e', 'a']; 
$b = ['a', 'a', 'd', 'e', 'c', 'a']; 

$a = array_filter($a, function ($element) use (&$b) { 
    if (($key = array_search($element, $b)) !== false) { 
     unset($b[$key]); 

     return false; 
    } 

    return true; 
}); 

demoです。

array_filterでは、述語関数(要素にtrueを返し、結果に保持する関数、そうでなければfalse)に基づいて配列をフィルタリングできます。我々の場合、この関数は要素を保持するかどうかを決定するために$bを使用します。参考の文節$bの場合は、途中でペアを削除できます。

+0

@sevavieti、あなたのコードは魅力的な働きをしていますが、やっていることについての説明も加えてください。 –

+0

@KumarAnand、はい、確かに問題ありません。喜んで助けてください。 – sevavietl

0

これは、異なるサイズの配列で機能し、値の位置を無視します。

$arr1 = removePairs($aArr, $bArr); 
$arr2 = removePairs($bArr, $aArr); 

print_r($arr1); 
print "<br>"; 
print_r($arr2); 

$res = count($arr1) + count($arr2); 
print $res; 

function removePairs($a, $b) 
{ 
    $r = array(); 

    foreach ($a as $index => $value) { 
     $found = array_search($value, $b); 

     if ($found !== false) { 
      $b[$found] .= '-'; 
     } else { 
      $r[] = $value; 
     } 
    } 

    return $r; 
} 
0

はあなたが私がこのことを知っているこの

foreach ($a as $aItem){ 
    if(!in_array($aItem, $b)){ 
     $arr1[] = $aItem; 
    } 
} 
var_dump($arr1); 
+0

残念ながら、値が重複しているため、これは機能しません。したがって、(a、a、b、c)と(b、c、a、a)は、関数を使用して空の配列になります。 – Forbs

0

のようなすべての配列をループが答えていることができます。しかし、受け入れられた答えは私のより複雑な解決策(注文が問題でない場合)よりも遅いです。

$a = ['a', 'b', 'd', 'c', 'e', 'a']; 
$b = ['a', 'a', 'd', 'e', 'c', 'a']; 
$ha = $hb = []; 
foreach ($a as $v) $ha[$v]++; 
foreach ($b as $v) $hb[$v]++; 

foreach (range('a', 'z') as $l) { 
    if (empty($ha[$l])) continue; 
    if (empty($hb[$l])) continue; 
    if ($ha[$l] > $hb[$l]) { 
     $ha[$l] = $ha[$l] - $hb[$l]; 
     unset($hb[$l]); 
     continue; 
    } 
    $hb[$l] = $hb[$l] - $ha[$l]; 
    unset($ha[$l]); 
} 
$a = []; 
$b = []; 
foreach ($ha as $l => $n) $a = array_merge($a, array_fill(0, $n, $l)); 
foreach ($hb as $l => $n) $b = array_merge($b, array_fill(0, $n, $l)); 

var_dump([$a, $b]); 

上記のコードは、受け入れられる答えがO(N^2)であるため、O(N)です。だからシンプルさやスピードから選択してください。

関連する問題