11

array2 にある array1 から値を取得するために array_diff() を使用しています。問題は、PHP ドキュメントに記載されているように、array1 からすべてのオカレンスが削除されることです。一度に1つだけ取り出したいです。

$array1 = array();
$array1[] = 'a';
$array1[] = 'b';
$array1[] = 'a';

$array2 = array();
$array2[] = 'a';

'b' だけの配列ではなく、1 つの 'a' と 1 つの 'b' を持つ配列を返す必要があります。

4

2 に答える 2

12

面白半分で、ふと思いついたもの。配列に文字列が含まれている限り機能します。

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

$counts = array_count_values($b);
$a = array_filter($a, function($o) use (&$counts) {
    return empty($counts[$o]) || !$counts[$o]--;
});

各配列を 1 回だけ走査するという利点があります。

実際に見てください

使い方:

最初に、2 番目の配列の各要素の頻度がカウントされます。これにより、キーが削除される要素であり$a、値が各要素を削除する回数である配列が得られます。

次に、 の要素を1 つずつarray_filter調べて、削除する必要がある要素を削除するために使用されます。$aフィルター関数は、検査中のアイテムと等しいキーがない場合、またはそのアイテムの残りの削除カウントがゼロに達した場合emptyに戻ります。の振る舞いは法案に完全に適合します。trueempty

上記のいずれにも当てはまらない場合はfalse、削除カウントを返して 1 減らします。Usingfalse || !$counts[$o]--は簡潔にするためのトリックです: カウントをデクリメントし、false最初からカウントが 0 より大きいことがわかっているため、常に に評価されます (そうでない場合は、||を評価した後に短絡しemptyます)。

于 2013-06-06T22:51:31.570 に答える
6

次のように、最初の配列から要素を 1 つずつ削除する関数を記述します。

function array_diff_once($array1, $array2) {
    foreach($array2 as $a) {
        $pos = array_search($a, $array1);
        if($pos !== false) {
            unset($array1[$pos]);
        }
    }

    return $array1;
}

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

print_r( array_diff_once($a, $b) );
于 2013-06-06T22:46:17.453 に答える