web-dev-qa-db-ja.com

php多次元配列は重複を削除します

この質問が重複して削除が必要かどうかはわかりませんが、他の場所で答えが見つからなかったので、質問してみます。

次のような2D配列があります。

Array
(
[0] => Array
    (
        [0] => dave
        [1] => jones
        [2] => [email protected]
    )

[1] => Array
    (
        [0] => john
        [1] => jones
        [2] => [email protected]

    )

[2] => Array
    (
        [0] => bruce
        [1] => finkle
        [2] => [email protected]
    )
)

メールが重複しているものを削除したいのですが。したがって、上記の例では、[] [0]または[] [2]のいずれかを削除したいと思います。名前などをチェックする必要はありません。単一の値に基づいてサブ配列を重複排除する必要があります。

現時点で私はこのようなものを持っています

  if(is_array($array) && count($array)>0){
  foreach ($array as $subarray) {
    $duplicateEmail[$subarray[2]] = isset($duplicateEmail[$subarray[2]]);
    unset($duplicateEmail[$subarray[2]]);
   }
  }

しかし、それは正しくありません。助けていただければ幸いです。

19
Kevin Carmody

配列インデックスの一意性を使用する簡単なソリューション:

$newArr = array();
foreach ($array as $val) {
    $newArr[$val[2]] = $val;    
}
$array = array_values($newArr);

注意1:上からわかるように、電子メールアドレスの最初の一致の代わりに最後の一致が使用されます。これは、2行目を次のように置き換えることで変更できます。

foreach (array_reverse($array) as $val) {

注意2:結果の配列のインデックスは多少混同されています。しかし、これは問題ではないと思います...

28
Dan Soap

はるかに簡単なソリューション。

$unique = array_map('unserialize', array_unique(array_map('serialize', $array)));

echo "<pre>";
print_r($unique);
15
Dipesh Parmar

array_unique() に対するユーザーのコメントには、これに対するいくつかの解決策があります。例えば

    function multi_unique($array) {
        foreach ($array as $k=>$na)
            $new[$k] = serialize($na);
        $uniq = array_unique($new);
        foreach($uniq as $k=>$ser)
            $new1[$k] = unserialize($ser);
        return ($new1);
    }

from http://uk.php.net/manual/en/function.array-unique.php#57202

8
robjmills
$array = array(
    array('dave','jones','[email protected]'),
    array('dave','jones','[email protected]'),
    array('dave','jones','[email protected]'),
    array('dave','jones','[email protected]'),
    array('dave','jones','[email protected]')   
);

$copy = $array; // create copy to delete dups from
$usedEmails = array(); // used emails

for( $i=0; $i<count($array); $i++ ) {

    if ( in_array( $array[$i][2], $usedEmails ) ) {
        unset($copy[$i]);
    }
    else {
        $usedEmails[] = $array[$i][2];
    }

}

print_r($copy);
3
Galen

2番目のパラメーターとしてnullを使用すると、array_column()の巧妙なキー割り当て機能を使用できます。これにより、サブアレイデータを完全にそのままにして、各サブアレイに新しいキーが割り当てられます。これらの一時キー(要素_[2]_別名「電子メール値」)により、重複する電子メールを持つ新しいサブ配列が以前のサブ配列を効果的に上書きします。重複が削除されたら、(必要に応じて)array_values()を使用して配列のインデックスを再作成します。

コード:( デモ

_$array = [
    ['dave', 'jones', '[email protected]'],
    ['john', 'jones', '[email protected]'],
    ['bruce', 'finkle', '[email protected]']
];

var_export(array_values(array_column($array, null, 2)));
_

出力:

_array (
  0 => 
  array (
    0 => 'bruce',
    1 => 'finkle',
    2 => '[email protected]',
  ),
  1 => 
  array (
    0 => 'john',
    1 => 'jones',
    2 => '[email protected]',
  ),
)
_
0
mickmackusa

私の提案:

protected function arrayUnique($array, $preserveKeys = false)
{
    $uniqueArray = array();
    $hashes = array();

    foreach ($array as $key => $value) {
        if (true === is_array($value)) {
            $uniqueArray[$key] = $this->arrayUnique($value, $preserveKeys);

        } else {
            $hash = md5($value);

            if (false === isset($hashes[$hash])) {
                if ($preserveKeys) {
                    $uniqueArray[$key] = $value;
                } else {
                    $uniqueArray[] = $value;
                }

                $hashes[$hash] = $hash;
            }
        }
    }

    return $uniqueArray;
}
0
Vail

2番目のパラメーターとしてユーザーSORT_REGULAR。

$uniqueArray = array_unique($array, SORT_REGULAR);
0