347

PHPで多次元配列から重複した値を削除するにはどうすればよいですか?

配列の例:

Array
(
    [0] => Array
    (
        [0] => abc
        [1] => def
    )

    [1] => Array
    (
        [0] => ghi
        [1] => jkl
    )

    [2] => Array
    (
        [0] => mno
        [1] => pql
    )

    [3] => Array
    (
        [0] => abc
        [1] => def
    )

    [4] => Array
    (
        [0] => ghi
        [1] => jkl
    )

    [5] => Array
    (
        [0] => mno
        [1] => pql
    )

)
4

18 に答える 18

281

5.2.9 以降、次のようにフラグarray_unique()を使用すると使用できます。SORT_REGULAR

array_unique($array, SORT_REGULAR);

これにより、関数は要素$a == $bが使用されているかのように等しいかどうかを比較します。これは、あなたの場合に最適です。

出力

Array
(
    [0] => Array
        (
            [0] => abc
            [1] => def
        )

    [1] => Array
        (
            [0] => ghi
            [1] => jkl
        )

    [2] => Array
        (
            [0] => mno
            [1] => pql
        )

)

ただし、ドキュメントには次のように記載されていることに注意してください。

array_unique()多次元配列で動作することを意図していません。

于 2013-08-22T07:01:44.983 に答える
67

同様の問題がありましたが、100%機能する解決策を見つけました。

<?php
    function super_unique($array,$key)
    {
       $temp_array = [];
       foreach ($array as &$v) {
           if (!isset($temp_array[$v[$key]]))
           $temp_array[$v[$key]] =& $v;
       }
       $array = array_values($temp_array);
       return $array;

    }


$arr="";
$arr[0]['id']=0;
$arr[0]['titel']="ABC";
$arr[1]['id']=1;
$arr[1]['titel']="DEF";
$arr[2]['id']=2;
$arr[2]['titel']="ABC";
$arr[3]['id']=3;
$arr[3]['titel']="XYZ";

echo "<pre>";
print_r($arr);
echo "unique*********************<br/>";
print_r(super_unique($arr,'titel'));

?>
于 2012-05-09T10:48:18.713 に答える
56

別の方法。キーも保持します。

function array_unique_multidimensional($input)
{
    $serialized = array_map('serialize', $input);
    $unique = array_unique($serialized);
    return array_intersect_key($input, $unique);
}
于 2008-11-21T14:36:55.963 に答える
21

array_unique()ドキュメントに関するユーザーのコメントには、これに対する多くの解決策があります。ここにそれらの1つがあります:

rbnsn ドットコムで kenrbnsn
2005 年 9 月 27 日 12:09

多次元配列用のさらに別の Array_Unique。私はこれを 2 次元配列でしかテストしていませんが、おそらくもっと一般化するか、再帰を使用するようにすることができます。

この関数は、serialize、array_unique、および unserialize 関数を使用して作業を行います。


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);
}

これはhttp://ca3.php.net/manual/en/function.array-unique.php#57202からのものです。

于 2008-11-21T03:07:40.563 に答える
3

mysqli ID などの特定のキーの重複を排除する必要がある場合は、次の簡単な関数を使用します。

function search_array_compact($data,$key){
    $compact = [];
    foreach($data as $row){
        if(!in_array($row[$key],$compact)){
            $compact[] = $row;
        }
    }
    return $compact;
}

ボーナス ポイント キーの配列を渡して外側の foreach を追加できますが、追加のキーごとに 2 倍遅くなります。

于 2014-11-08T07:17:22.437 に答える
3

多次元配列を一意にする非常に簡単で論理的な方法は次のとおりです。

次のような配列がある場合:

Array
(
    [Key1] => Array
        (
            [0] => Value1
            [1] => Value2
            [2] => Value1
            [3] => Value3
            [4] => Value1
        )
    [Key2] => Array
        (
            [0] => Value1
            [1] => Value2
            [2] => Value1
            [3] => Value3
            [4] => Value4
        )
)

foreachこれを解決するために使用します:

foreach($array as $k=>$v){
    $unique=array_unique($v);
    $array[$k]=$unique;
}

次の結果が得られます。

Array
(
    [Key1] => Array
        (
            [0] => Value1
            [1] => Value2
            [3] => Value3
        )
    [Key2] => Array
        (
            [0] => Value1
            [1] => Value2
            [3] => Value3
            [4] => Value4
        )
)

キーの順序を並べ替えたい場合は、

foreach($array as $k=>$v){
    $unique= array_values(array_unique($v));
    $array[$k]=$unique;
}

この操作により、次のように配置されたキー値が得られます。

Array
(
    [Key1] => Array
        (
            [0] => Value1
            [1] => Value2
            [2] => Value3
        )
    [Key2] => Array
        (
            [0] => Value1
            [1] => Value2
            [2] => Value3
            [3] => Value4
        )
)

これですべてがクリアされることを願っています。

于 2018-01-19T13:22:42.137 に答える
2

次のような配列がある場合:

(users はアレイの名前です)

Array=>
 [0] => (array)
   'user' => 'john'
   'age' => '23'
 [1] => (array)
  'user' => 'jane'
  'age' => '20'
 [2]=> (array)
  'user' => 'john'
  'age' => '23'

重複を削除したい...次に:

$serialized = array();
for ($i=0; $i < sizeof($users); $i++) { 
  $test = in_array($users['user'], $serialized);
    if ($test == false) {
      $serialized[] = $users['user'];
    }
 }

解決策になることができます:P

于 2015-08-07T18:45:40.760 に答える
1

人々がarray_unique()非常に遅いと言っているように、これは私が 1 レベルの多次元配列に使用するスニペットです。

$serialized_array = array_map("serialize", $input);

foreach ($serialized_array as $key => $val) {
     $result[$val] = true;
}

$output = array_map("unserialize", (array_keys($result)));

php.netの関数ページの最初のユーザー投稿ノートを参照array_unique()

于 2015-04-18T19:01:05.647 に答える
0

このような配列がある場合

data = array
(
[0] => array
(
    [subject] => a
    [object] => c
),
[1] => array
(
    [subject] => b
    [object] => d
),
[2] => array
(
    [subject] => d
    [object] => b
),
[3] => array
(
    [subject] => d
    [object] => c
),
[4] => array
(
    [subject] => c
    [object] => a
),
[5] => array
(
    [subject] => c
    [object] => d
)
)

そして、次のような配列を取得したい:

data = array
(
[0] => array
(
    [subject] => a
    [object] => c
),
[1] => array
(
    [subject] => b
    [object] => d
),
[2] => array
(
    [subject] => d
    [object] => c
)
)

また

data = array
(
[0] => array
(
    [subject] => d
    [object] => b
),
[1] => array
(
    [subject] => c
    [object] => a
),
[2] => array
(
    [subject] => c
    [object] => d
)
)

次のコードが役立ちます

    $data1 = array();
    $data1 = $data;
    for($q=0;$q<count($data);$q++)
    {
            for($p=0;$p<count($data1);$p++)
            {
                    if (($data[$q]["subject"] == $data1[$p]["object"]) && ($data[$q]["object"] == $data1[$p]["subject"]))
                    {
                            $data1[$p]["subject"] = $data[$q]["subject"];
                            $data1[$p]["object"] = $data[$q]["object"];
                    }
            }
    }
    $data1 = array_values(array_map("unserialize", array_unique(array_map("serialize", $data1))));
    $data = $data1;
于 2014-11-29T17:08:48.070 に答える
0

この問題についてよく考えた結果、最適なソリューションは 2 つのルールに従う必要があると判断しました。

  1. スケーラビリティのために、配列をその場で変更します。新しい配列へのコピーなし
  2. パフォーマンスのために、各比較は 1 回だけ行う必要があります

それを念頭に置いて、PHP のすべての癖を考慮して、私が思いついた解決策を以下に示します。他のいくつかの回答とは異なり、必要なキーに基づいて要素を削除する機能があります。入力配列は数字キーであることが期待されます。

$count_array = count($input);
for ($i = 0; $i < $count_array; $i++) {
    if (isset($input[$i])) {
        for ($j = $i+1; $j < $count_array; $j++) {
            if (isset($input[$j])) {
                //this is where you do your comparison for dupes
                if ($input[$i]['checksum'] == $input[$j]['checksum']) {
                    unset($input[$j]);
                }
            }
        }
    }
}

唯一の欠点は、反復が完了したときにキーが正しくないことです。これは、後で foreach ループのみを使用する場合は問題ありませんが、for ループを使用する必要がある場合は$input = array_values($input);、上記の後にキーの番号を付け直すことができます。

于 2015-03-05T14:04:48.637 に答える
0

シリアル化と一意化の代替手段

$test = [
    ['abc','def'],
    ['ghi','jkl'],
    ['mno','pql'],
    ['abc','def'],
    ['ghi','jkl'],
    ['mno','pql'],
];

$result = array_reduce(
    $test,
    function($carry,$item){
        if(!in_array($item,$carry)) {
            array_push($carry,$item);
        }
        return $carry;
    },
    []
);

var_dump($result);

/*
 php unique.php
array(3) {
    [0] =>
        array(2) {
            [0] =>
                string(3) "abc"
            [1] =>
                string(3) "def"
        }
    [1] =>
        array(2) {
            [0] =>
                string(3) "ghi"
            [1] =>
                string(3) "jkl"
        }
    [2] =>
        array(2) {
              [0] =>
                  string(3) "mno"
              [1] =>
                  string(3) "pql"
        }
}

*/

于 2014-11-06T23:04:48.500 に答える