Как удалить повторяющиеся значения из многомерного массива в PHP



Как я могу удалить повторяющиеся значения из многомерного массива в 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
)

)
675   17  

17 ответов:

вот еще один способ. Промежуточные переменные не сохраняются.

мы использовали это для удаления дубликатов результатов из различных перекрывающихся запросов.

$input = array_map("unserialize", array_unique(array_map("serialize", $input)));

С 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() не предназначен для работы с многомерными массивами.

У меня была аналогичная проблема, но я нашел для нее 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'));

?>

другой путь. Сохранит ключи также.

function array_unique_multidimensional($input)
{
    $serialized = array_map('serialize', $input);
    $unique = array_unique($serialized);
    return array_intersect_key($input, $unique);
}

комментарии других пользователей о array_unique () документация есть много решений для этого. Вот один из них:

kenrbnsn в rbnsn dot com
27-Sep-2005 12: 09

еще один Array_Unique для multi-demensioned массивов. Я только проверил это на двух-пониженных массивах, но, вероятно, его можно было бы обобщить для большего количества или использовать рекурсию.

эта функция использует serialize, 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);
}

Это от http://ca3.php.net/manual/en/function.array-unique.php#57202.

Если "удалить дубликаты" означает "удалить дубликаты, но пусть один там", решение может быть применить array_unique(...) в колонке "идентификатор", а затем снять в исходном массиве все ключи, которые были удалены из массива столбцов:

$array = [
    [
        'id' => '123',
        'foo' => 'aaa',
        'bar' => 'bbb'
    ],
    [
        'id' => '123',
        'foo' => 'ccc',
        'bar' => 'ddd'
    ],
    [
        'id' => '567',
        'foo' => 'eee',
        'bar' => 'fff'
    ]
];

$ids = array_column($array, 'id');
$ids = array_unique($ids);
$array = array_filter($array, function ($key, $value) use ($ids) {
    return in_array($value, array_keys($ids));
}, ARRAY_FILTER_USE_BOTH);

результат:

Array
(
    [0] => Array
        (
            [id] => 123
            [foo] => aaa
            [bar] => bbb
        )

    [2] => Array
        (
            [id] => 567
            [foo] => eee
            [bar] => fff
        )

)

просто используйте параметр SORT_REGULAR в качестве второго параметра.

$uniqueArray = array_unique($array, SORT_REGULAR);

Если вам нужно устранить дубликаты на определенных ключах, таких как идентификатор mysqli, вот простая функция

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

Бонусные Баллы Вы можете передать массив ключей и добавить внешний foreach, но это будет в 2 раза медленнее на дополнительный ключ.

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => john
        )

    [1] => Array
        (
            [id] => 2
            [name] => smith
        )

    [2] => Array
        (
            [id] => 3
            [name] => john
        )

    [3] => Array
        (
            [id] => 4
            [name] => robert
        )

)

$temp = array_unique(array_column($array, 'name'));
$unique_arr = array_intersect_key($array, $temp);

Это позволит удалить дубликаты из массива. уникальный по ключу

Если у вас есть массив, как это:

(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

простое для чтения решение, вероятно, не самое эффективное:

function arrayUnique($myArray){
    if(!is_array($myArray))
        return $myArray;

    foreach ($myArray as &$myvalue){
        $myvalue=serialize($myvalue);
    }

    $myArray=array_unique($myArray);

    foreach ($myArray as &$myvalue){
        $myvalue=unserialize($myvalue);
    }

    return $myArray;

} 

многие люди спрашивали меня, как сделать уникальный многомерный массив. Я взял ссылку из вашего комментария, и это помогает мне.

прежде всего, спасибо @jeromegamez @daveilers за ваше решение. Но каждый раз, когда я дал ответ, они спросили меня, как это 'сериализации' и 'восстановить' работает. Вот почему я хочу поделиться с вами причиной этого, чтобы это помогло большему количеству людей понять концепцию этого.

Я объясняю, почему мы используем 'serialize' и "unserialize" в шагах:

Шаг 1: преобразование многомерного массива в одномерный массив

чтобы преобразовать многомерный массив в одномерный массив, сначала создайте представление потока байтов всех элементов (включая вложенные массивы) внутри массива. функция serialize () может генерировать представление байтового потока значения. Чтобы создать представление потока байтов всех элементов, вызовите функцию serialize () внутри array_map() функция как функция обратного вызова. Результатом будет одномерный массив независимо от того, сколько уровней имеет многомерный массив.

Шаг 2: Сделайте значения уникальными

чтобы сделать этот одномерный массив уникальным, используйте функцию array_unique ().

Шаг 3: верните его в многомерный массив

хотя массив теперь уникален, значения выглядят как представление потока байтов. Чтобы вернуть его обратно многомерный массив, используйте функцию unserialize ().

$input = array_map("unserialize", array_unique(array_map("serialize", $input)));

еще раз спасибо за все это.

очень простой и логичный способ унифицировать многомерный массив заключается в следующем,

если у вас есть массив, как это:

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

Я надеюсь, что это все прояснит.

альтернатива сериализации и уникальности

$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"
        }
}

*/

если у вас есть массив такой

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;

Я много думал над этой проблемой и определил, что оптимальное решение должно следовать двум правилам.

  1. для масштабируемости измените массив на месте; нет копирования в новый массив
  2. для исполнения, каждое сравнение должно быть сделано только один раз

имея это в виду и учитывая все причуды 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); после изменения нумерации ключей.

как говорят люди array_unique() очень медленно, Вот фрагмент, который я использую для одного уровня многомерного массива.

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

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

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

ссылка первый пользователь внес Примечание array_unique() страница функции внутри php.net

Comments

    Ничего не найдено.