Гость
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / слить два многомерных массива / 10 сообщений из 10, страница 1 из 1
13.01.2012, 12:43
    #37612778
Пионэр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
слить два многомерных массива
Функция array_merge_recursive() сливает многомерные массивы, но, если в них встречается числовой ключ , вместо желаемого слияния получается добавление массива с новым числовым ключом.

Возможно кто-то имеет готовое решение?
(то есть,: как слить массивы, в чтобы числовой ключ не расщеплял ветку)

Проиллюстрирую:

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
// пример #1 - без числовых ключей
// имеем
$a['post']['title']['_mess_'] = 'попробуй ещё';
$a['post']['title']['_val_'] = 'введите текст';

// добавляем
$b['post']['title']['_err_'] = 'WTF!';

// сливаем
$result = array_merge_recursive ($a, $b);

// получаем превосходный результат: массивы слиты безупречно
Array
(
    [post] => Array
        (
            [title] => Array
                (
                    [_mess_] => попробуй ещё
                    [_val_] => введите текст
                    [_err_] => WTF!
                )

        )

)



// пример #2 - числовыми ключами
// имеем
$a['post'][3]['title']['_mess_'] = 'попробуй ещё';
$a['post'][3]['title']['_val_'] = 'введите текст';

// добавляем
$b['post'][3]['title']['_err_'] = 'WTF!';

// сливаем
$result = array_merge_recursive ($a, $b);


// результат: массивы разветвляются..
Array
(
    [post] => Array
        (
            [3] => Array
                (
                    [title] => Array
                        (
                            [_mess_] => попробуй ещё
                            [_val_] => введите текст
                        )

                )

            [4] => Array
                (
                    [title] => Array
                        (
                            [_err_] => WTF!
                        )

                )

        )

)
...
Рейтинг: 0 / 0
13.01.2012, 13:47
    #37612967
Пионэр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
слить два многомерных массива
Решил такой вот несложной рекурсией:
(сливайте на здоровье!)


Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
// сливаем многомерные массивы не взирая на ключи

function merge($dest, $new) {

	foreach ($new as $k => $v) {
		if(is_array($v) and isset($dest[$k])){
			$dest[$k] = merge($dest[$k], $v);}
		else{
			$dest[$k] = $new[$k];}
	}

	return $dest;
}



Только не пойму в чём подвох: почему этой функции нет в "стандартной комплектации" PHP?
собственно эти и сбило с толку (думал - мало ли чего...)
...
Рейтинг: 0 / 0
17.01.2012, 14:25
    #37618030
Ренат
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
слить два многомерных массива
Пионэр,

просто она ну очень редко нужна....
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
08.04.2013, 07:25
    #38216496
слить два многомерных массива
Я, конечно, понимаю, что прошло уже почти полтора года со старта топика, но в гугле он (топик) на первом месте по запросу "php слить многомерные массивы", а предложенная функция-то неправильная..

В общем, вот правильный вариант, чтобы народ из поиска бездумно не копировал не правильный вариант:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
function _array_merge_recursive($dest, $new) {
	foreach ($new as $k => $v) {
		if (is_array($v) && isset($dest[$k]) && !is_numeric($k)) {
			$dest[$k] = _array_merge_recursive($dest[$k], $v);
		} else if (!is_numeric($k)) {
			$dest[$k] = $new[$k];
		} else {
			$dest[] = $new[$k];
		}
	}
	return $dest;
}
...
Рейтинг: 0 / 0
08.04.2013, 07:39
    #38216499
слить два многомерных массива
Даже вот так:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
function _array_merge_recursive($dest, $new) {
	if (!is_array($dest) &&  is_array($new)) return $new;
	if ( is_array($dest) && !is_array($new)) return $dest;
	if (!is_array($dest) && !is_array($new)) return array();
	foreach ($new as $k => $v) {
		if (is_array($v) && isset($dest[$k]) && !is_numeric($k)) {
			$dest[$k] = _array_merge_recursive($dest[$k], $v);
		} else if (!is_numeric($k)) {
			$dest[$k] = $new[$k];
		} else {
			$dest[] = $new[$k];
		}
	}
	return $dest;
}



Кто может написать лучше - напишите (-:
...
Рейтинг: 0 / 0
08.04.2013, 07:46
    #38216501
ScareCrow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
слить два многомерных массива
предлагаю для начала написать правильно. тоесть так, чтобы хотябы работало.
...
Рейтинг: 0 / 0
10.04.2013, 01:39
    #38219629
слить два многомерных массива
ScareCrow, у меня работает - проблем с этим не испытываю)
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
28.10.2016, 18:18
    #39336571
слить два многомерных массива
Карташов Алексей,

не работает! Ошибка! Вот так работает. :)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
function _array_merge_recursive_keynum($dest, $new) {
	if (!is_array($dest) &&  is_array($new)) return $new;
	if ( is_array($dest) && !is_array($new)) return $dest;
	if (!is_array($dest) && !is_array($new)) return array();
	foreach ($new as $k => $v) {
		if(is_array($v) and isset($dest[$k]) && is_numeric($k)){
			$dest[$k] = array_merge_recursive($dest[$k], $v);
		    print_r("1");
		} else if (!is_numeric($k)) {
			$dest[$k] = $new[$k];
		} else {
			$dest[] = $new[$k];
		}
	}
	return $dest;
}
...
Рейтинг: 0 / 0
28.09.2017, 01:13
    #39527372
kalamfur
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
слить два многомерных массива
я бы написал так:

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
function array_fullmerge(array $a, array $b) {
	foreach ($b as $key=>$val) {

		if(is_array($val)){
			if(isset($a[$key]) && is_array($a[$key])){
				$a[$key] = array_fullmerge($a[$key], $val);
			}else{
				$a[$key] = $val;
			}
		} else {
			$a[$key] = $val;
		}
	}
	return $a;
}



ЗЫ: Не пинайте , что откопал эту тему, понадобилось слить массивы, думать отвык, чуть что лезу в гугл, а тут это..
...
Рейтинг: 0 / 0
02.10.2017, 10:16
    #39529221
Няшик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
слить два многомерных массива
Вообще - то, Пионэр, дал правильный код. Просто слегка ошибся с действием проверки ключа. Надо было Isset проверить первым делом.

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
<?php
$a  = array();
$b  = array();
$a['post'][3]['title']['_mess_'] = 'попробуй ещё';
$a['post'][3]['title']['_val_'] = 'введите текст';

// добавляем
$b['post'][3]['title']['_err_'] = 'WTF!';
$b['post'][3]['title3']['_err_4'] = 'WTF!';

function merge(array $ArrDast, array $ArrSource) {
    foreach($ArrSource as $idx => $value) {
        if(isset($ArrDast[$idx]) and is_array($ArrDast[$idx])) {
            $ArrDast[$idx] = merge($ArrDast[$idx], $value);
        } else {
            $ArrDast[$idx] = $value;
        }
    }
    return $ArrDast;
}

print_r(merge($a, $b));





Результат

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
Array
(
    [post] => Array
        (
            [3] => Array
                (
                    [title] => Array
                        (
                            [_mess_] => попробуй ещё
                            [_val_] => введите текст
                            [_err_] => WTF!
                        )

                    [title3] => Array
                        (
                            [_err_4] => WTF!
                        )

                )

        )

)
...
Рейтинг: 0 / 0
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / слить два многомерных массива / 10 сообщений из 10, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]