- Намиране на разлики в многомерни масиви?
12
WT форуми -> PHP MySQL ASP.NET -> Намиране на разлики в многомерни масиви?
Създайте нова тема Напишете отговор 
Автор Съобщение
streleca_stz
Турист
Турист

Регистриран на: 13/07/2009 12:30 am

Support: 6
Bonus: 12
Мнения: 486
Мнение 18/08/2017 12:02 pm     Намиране на разлики в многомерни масиви? Отговорете с цитат


Здравейте,
Опитвам се да проверя дали 2 многомерни масива се различават един спрямо друг и да извадя всички редове, които се различават. Проблемът е, че стигнах до положението, в което проверявам за разлики в стойностите на масивите от първо ниво, но навътре ако има разлики няма да ги отчете. Ето пример:
PHP code:
$arr1 = array(
'key1' => 2,
'key2' => 4,
'key3' => array(1,5,2,7),
'key4' => 1,
);

$arr2 = array(
'key1' => 2,
'key2' => 5,
'key3' => array(1,2,7),
'key4' => 5,
);

$diff = array_diff(array_merge($arr1, $arr2), array_intersect($arr1,$arr2));

В случая $diff ще върне:
PHP code:
Array
(
[key2] => 5
[key4] => 5
)
което ме устройва, но до известна степен, защото масивът в 'key3' също има разлики, които не ги намира. Ще се радвам ако някой може да съдейства как мога да допълня вече измисленото, за да търси от всички нива за разлики в стойностите. Smile
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение Изпрати мейла
Revelation
Турист
Турист

Регистриран на: 24/03/2013 3:23 pm

Support: 40
Bonus: 80
Мнения: 563
Мнение 18/08/2017 2:06 pm      Отговорете с цитат


PHP code:

<?php

$arr1 = array(
'key1' => 2,
'key2' => 4,
'key3' => array(1,5,2,7),
'key4' => 1,
);

$arr2 = array(
'key1' => 2,
'key2' => 5,
'key3' => array(1,2,7),
'key4' => 5,
);

function value_comparison($a, $b) {
if ( is_array($a) && is_array($b) ) {
$diff = array_diff($a, $b);
if ( sizeof($diff) > 0 ) return -1;
else return 0;
} else {
if ( $a === $b ) {
return 0;
}
return ($a > $b) ? 1 : -1;
}
}

function key_comparison($a, $b) {
if ( $a === $b ) return 0;
return ($a > $b) ? 1 : -1;
}

$diff = array_udiff_uassoc($arr1, $arr2, "value_comparison", "key_comparison");

print_r($diff);


Това би трябвало да ти свърши работа.
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
Revelation
Турист
Турист

Регистриран на: 24/03/2013 3:23 pm

Support: 40
Bonus: 80
Мнения: 563
Мнение 18/08/2017 2:16 pm      Отговорете с цитат


@Fakeheal сварих да ти прочета мнението.

PHP code:

function value_comparison($a, $b) {
if ( is_array($a) && is_array($b) ) {
$diff = array_udiff_assoc($a, $b, "value_comparison");
if ( sizeof($diff) > 0 ) return -1;
else return 0;
} else {
if ( $a === $b ) {
return 0;
}
return ($a > $b) ? 1 : -1;
}
}
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
Fakeheal
Support
Support

Регистриран на: 17/04/2010 8:37 am

Support: 342
Bonus: 682
Мнения: 2564
Мнение 18/08/2017 2:18 pm      Отговорете с цитат


А
'key3' => array(1,2, array(1,4,4,5, array(10, 15, 20)), 7),

?

Последната промяна е направена от Fakeheal на 18/08/2017 2:22 pm; мнението е било променяно общо 1 път
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
Revelation
Турист
Турист

Регистриран на: 24/03/2013 3:23 pm

Support: 40
Bonus: 80
Мнения: 563
Мнение 18/08/2017 2:21 pm      Отговорете с цитат


Резултат след промяната.

PHP code:

Array 1:
Array
(
[key1] => 2
[key2] => 4
[key3] => Array
(
[0] => 1
[1] => 5
[2] => 7
[3] => Array
(
[0] => 1
[1] => 4
[2] => 3
)

)

[key4] => 1
)


Array 2:
Array
(
[key1] => 2
[key2] => 5
[key3] => Array
(
[0] => 1
[1] => 5
[2] => 7
[3] => Array
(
[0] => 1
[1] => 2
[2] => 3
)

)

[key4] => 5
)


Differences:
Array
(
[key2] => 4
[key3] => Array
(
[0] => 1
[1] => 5
[2] => 7
[3] => Array
(
[0] => 1
[1] => 4
[2] => 3
)

)

[key4] => 1
)


П.П. Дадох резултат с грешни данни.

Последната промяна е направена от Revelation на 18/08/2017 2:23 pm; мнението е било променяно общо 1 път
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
Fakeheal
Support
Support

Регистриран на: 17/04/2010 8:37 am

Support: 342
Bonus: 682
Мнения: 2564
Мнение 18/08/2017 2:23 pm      Отговорете с цитат


При мен това:


<?php

$arr1 = array(
        'key1' => 2,
        'key2' => 4,
        'key3' => array(1,5,2,7),
        'key4' => 1,
);

$arr2 = array(
        'key1' => 2,
        'key2' => 5,
        'key3' => array(1,2, array(1,4,4,5, array(10, 15, 20)), 7),
        'key4' => 5,
);

function value_comparison($a, $b) {
    if ( is_array($a) && is_array($b) ) {
        $diff = array_udiff_assoc($a, $b, "value_comparison");
        if ( sizeof($diff) > 0 ) return -1;
        else return 0;
    } else {
        if ( $a === $b ) {
            return 0;   
        }
        return ($a > $b) ? 1 : -1;
    }
}

function key_comparison($a, $b) {
    if ( $a === $b ) return 0;
    return ($a > $b) ? 1 : -1;
}

$diff = array_udiff_uassoc($arr1, $arr2, "value_comparison", "key_comparison");

print_r($diff);


Връща:


Array
(
    [key2] => 4
    [key3] => Array
        (
            [0] => 1
            [1] => 5
            [2] => 2
            [3] => 7
        )

    [key4] => 1
)


Къде ми е грешката?

7 не трябва ли да не е разликата тъй като позицията и стойността е еднаква?
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
Revelation
Турист
Турист

Регистриран на: 24/03/2013 3:23 pm

Support: 40
Bonus: 80
Мнения: 563
Мнение 18/08/2017 2:31 pm      Отговорете с цитат


Хм, да, би трябвало да не е разлика. Сега ще видя от къде идва проблема.
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
Revelation
Турист
Турист

Регистриран на: 24/03/2013 3:23 pm

Support: 40
Bonus: 80
Мнения: 563
Мнение 18/08/2017 2:54 pm      Отговорете с цитат


Ами реално няма проблем в ситуацията. Просто вади целия масив, защото не е същия като във втория масив.

Пробвай следното. Направи един тест като направиш key3 с еднакви масиви и дълбочини. Да са идентични.
После направи следния тест: на един от двата масива направи промяна в най-вътрешния масив и като разлики ще ти даде отново целия key3 масив от $arr1.
Вероятно ще трябва да се напише изцяло нов алгоритъм, за да може да показва само разликите в дълбочина.

П.П. Въпроса е, нужно ли му е с точност да знае разликите във вътрешните масиви или просто иска да знае, че там има разлики.
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
lam3r4370
Активен
Активен

Регистриран на: 20/08/2008 6:12 pm

Support: 131
Bonus: 244
Мнения: 3410
Мнение 18/08/2017 4:06 pm      Отговорете с цитат


Ако иска, може да пробва с рекурсия, не знам дали е оптималният вариант

https://stackoverflow.com/questions/12246039/multidimensional-array-difference-php

Грешка, горният код не работи с дълбочина>2

Edit2: но по-надолу от първия отговор има работещи
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение Посетете сайта на потребителя
lam3r4370
Активен
Активен

Регистриран на: 20/08/2008 6:12 pm

Support: 131
Bonus: 244
Мнения: 3410
Мнение 18/08/2017 6:42 pm      Отговорете с цитат


ttta написа:
Ми ако искат, то си е задължително да се ползва рекурсия. Каквато се ползва в горния код...

Много весел форум, ей...


Имах предвид рекурсия без готовите diff функции.



Цитат:
Лошо. Бедния речников запас се преодолява с четене на повечко литература - художествена.


Явно не си чел достатъчно, иначе щеше да знаеш кога се използва пълен и кратък член.
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение Посетете сайта на потребителя
Revelation
Турист
Турист

Регистриран на: 24/03/2013 3:23 pm

Support: 40
Bonus: 80
Мнения: 563
Мнение 18/08/2017 6:44 pm      Отговорете с цитат


ttta написа:
Fakeheal написа:
ttta написа:
Ми ако искат, то си е задължително да се ползва рекурсия. Каквато се ползва в горния код...

Много весел форум, ей...

аз само мога да кажа да ходиш да се гръмнеш, лол

Лошо. Бедния речников запас се преодолява с четене на повечко литература - художествена.

Ама кажи честно, след като се занимаваш от поне 7 години с програмиране, наистина ли не можеш да видиш рекурсивното извикване?
За очевадните грешки няма да питам, щото гражданина, автор, трудно преглъща критика...


Ама хайде дай най-накрая код, та да се научим и ние. Дай да видим твоето решение. То философията е най-лесна.
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
Revelation
Турист
Турист

Регистриран на: 24/03/2013 3:23 pm

Support: 40
Bonus: 80
Мнения: 563
Мнение 18/08/2017 7:32 pm      Отговорете с цитат


Да, по неговата логика. Very Happy


Иначе, ето решение.
PHP code:

$arr1 = array(
'key1' => 2,
'key2' => 4,
'key3' => array(1, 2,
array(1,4,3,5,
array(10, 13, 20)),
7),
'key4' => 1,
);

$arr2 = array(
'key1' => 2,
'key2' => 5,
'key3' => array(1,2,
array(1,4,4,5,
array(10, 15, 21)),
7),
'key4' => 5,
);

function array_diff_recursive($a1, $a2) {
$result = array();

foreach( $a1 as $k=>$v ) {
if ( array_key_exists($k, $a2) && (is_array($v) && is_array($a2[$k])) ) {
$result[$k] = array_diff_recursive($v, $a2[$k]);
} else {
if ( !isset($a2[$k]) || $v !== $a2[$k] ) {
$result[$k] = $v;
}
}
}

return $result;
}

$multi_diff = array_diff_recursive($arr1, $arr2);


Резултат:
PHP code:

Array 1:
Array
(
[key1] => 2
[key2] => 4
[key3] => Array
(
[0] => 1
[1] => 2
[2] => Array
(
[0] => 1
[1] => 4
[2] => 3
[3] => 5
[4] => Array
(
[0] => 10
[1] => 13
[2] => 20
)

)

[3] => 7
)

[key4] => 1
)


Array 2:
Array
(
[key1] => 2
[key2] => 5
[key3] => Array
(
[0] => 1
[1] => 2
[2] => Array
(
[0] => 1
[1] => 4
[2] => 4
[3] => 5
[4] => Array
(
[0] => 10
[1] => 15
[2] => 21
)

)

[3] => 7
)

[key4] => 5
)


Multi diff:
Array
(
[key2] => 4
[key3] => Array
(
[2] => Array
(
[2] => 3
[4] => Array
(
[1] => 13
[2] => 20
)

)

)

[key4] => 1
)


ЕДИТ: Малко промяна по кода. Махнах някои излишни проверки.

Последната промяна е направена от Revelation на 18/08/2017 8:12 pm; мнението е било променяно общо 1 път
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
Покажи мнения от преди:    
Създайте нова тема   Напишете отговор    web-tourist.net Форуми -> PHP MySQL ASP.NET Часовете са според зоната GMT + 2 Часа
12
Страница 1 от 2


 
Идете на:  
Не Можете да пускате нови теми
Не Можете да отговаряте на темите
Не Можете да променяте съобщенията си
Не Можете да изтривате съобщенията си
Не Можете да гласувате в анкети