Убрать повторяющиеся значения из двумерного массива

zerkms

TDD infected
Команда форума
Эдди
Что ещё ответить в топике, в котором не то что деталей - а нет даже самого вопроса?

Сочувствие - единственный ответ.
 

Эдди

Новичок
Есть массив:
PHP:
Array
(
    [0] => Array
        (
            [key1] => A
            [key2] => B
        )

    [2] => Array
        (
            [key1] => B
            [key2] => C
        )

    [4] => Array
        (
            [key1] => B
            [key2] => C
        )

    [6] => Array
        (
            [key1] => C
            [key2] => D
        )
)
Как убрать повторяющиеся значения?
 

zerkms

TDD infected
Команда форума
Что должно быть в результате? Тупо массив A B C D?
PHP:
$arr = array(array('a', 'b'), array('b', 'c'), array('c', 'd', 'c', 'c'));

$result = array_reduce($arr, function($a, $b) {
    return array_unique($a += $b);
}, array());

var_dump($result); // array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" }
 

zerkms

TDD infected
Команда форума
Встроенными функциями никак. Только вручную через сериализацию и сравнение.
PHP:
<?php

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

$result = array_reduce($arr, function($a, $b) {
    static $stored = array();
    
    $hash = md5(serialize($b));
    
    if (!in_array($hash, $stored)) {
        $stored[] = $hash;
        $a[] = $b;
    }
    
    return $a;
}, array());

var_dump($result); // array(2) { [0]=> array(2) { [0]=> string(1) "a" [1]=> string(1) "b" } [1]=> array(2) { [0]=> string(1) "b" [1]=> string(1) "c" } }
 

zerkms

TDD infected
Команда форума
Эдди
Да те же яйца. Просто у меня получился "однострочник". Но логика-то та же самая.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
зачем эти хеши, сериализация?
PHP:
$arr2 = $arr;
while (list($k1, $v1) = each($arr)) {
    $res[$k1] = $v1;
    foreach($arr2 as $k2=>$v2){
        if ($k1===$k2) continue;
        if (!is_array($v1) || !is_array($v2)) throw new exception();
        if (!array_diff($v1,$v2)){
            unset ($arr[$k2],$arr2[$k2]);
        }
    }
}
 

zerkms

TDD infected
Команда форума
grigori
От тебя видеть

while (list($k1, $v1) = each($arr)) {

Это шутка, да? :-S

По поводу кода - т.е. ты считаешь что 2 цикла лучше, чем 1?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
1. нет, не шутка
foreach копирует массив перед циклом, а each - двигает указатель
следствие - цикл будет пропускать удаленные элементы

2. у нас обоих тут 3 цикла: у тебя 2й спрятан в in_array, 3й - в сериализации. Ты не сделаешь проверку 2-мерного массива 1м циклом :)
Алгоритмически мой код лучше тем, что дубликаты, найденные в ходе исполнения, исключаются из дальнейших вычислений. Ну, и не хочу быть занудой, но риски коллизий ... :)
 

zerkms

TDD infected
Команда форума
grigori
1. foreach копирует массив только тогда, когда его невозможно не копировать.
2. Омг, а у тебя ещё array_diff, третья вложенность.

"Ты не сделаешь проверку 2-мерного массива 1м циклом" --- если я упрусь в это место - я сделаю хэш ключом массива.
 

fixxxer

К.О.
Партнер клуба
Риски коллизий в жопу.

Экономия на copy-on-write (кстати, гарантированный способ избежать копирования, если уж так хочется - foreach ($arr as &$val)) по сравнению с алгоритмической сложностью - тоже в жопу (а при объемах массива менее чем 100500 вообще оптимизации в жопу).

А вот перед сериализацией я бы массив сортировал, а то может получиться не совсем то ;) Также вопрос, считаем ли одинаковыми (int)1 и (string)"1".
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
grigori
1. foreach копирует массив только тогда, когда его невозможно не копировать.
Читаем мануал :)
Note: Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer.


2. Омг, а у тебя ещё array_diff, третья вложенность.
Как и у тебя!

"Ты не сделаешь проверку 2-мерного массива 1м циклом" --- если я упрусь в это место - я сделаю хэш ключом массива.
Я не вижу в задаче ТСа условий эффективности исполнения.
 

zerkms

TDD infected
Команда форума
fixxxer
Вот я тоже думал про сортировку. Но тут очень зависит от задачи. В зависимости от того как трактовать требования - сортировка или нужна, или не нужна.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
fixxxer ежу понятно, что спор глубоко теоретический :)
 

zerkms

TDD infected
Команда форума
Читаем мануал :)
Note: Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer.



Как и у тебя!
Я не вижу в задаче ТСа условий эффективности исполнения.[/quote]
1. Ты уверен, что тут не работает COW?
2. Где у меня? У меня два цикла, у тебя три
3. Не было, но у меня возможность есть, а у тебя нет :-P
 
Сверху