Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PHP, Perl, Python Новый топик    Ответить
 слить два многомерных массива  [new]
Пионэр
Member

Откуда: sPb
Сообщений: 57
Функция array_merge_recursive() сливает многомерные массивы, но, если в них встречается числовой ключ, вместо желаемого слияния получается добавление массива с новым числовым ключом.

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

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

// пример #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!
                        )

                )

        )

)
13 янв 12, 12:43    [11898477]     Ответить | Цитировать Сообщить модератору
 Re: слить два многомерных массива  [new]
Пионэр
Member

Откуда: sPb
Сообщений: 57
Решил такой вот несложной рекурсией:
(сливайте на здоровье!)


// сливаем многомерные массивы не взирая на ключи

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?
собственно эти и сбило с толку (думал - мало ли чего...)
13 янв 12, 13:47    [11899104]     Ответить | Цитировать Сообщить модератору
 Re: слить два многомерных массива  [new]
Ренат
Member

Откуда: Елабуга & Казань & Москва & Набережные челны
Сообщений: 4225
Пионэр,

просто она ну очень редко нужна....
17 янв 12, 14:25    [11917796]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: слить два многомерных массива  [new]
Карташов Алексей
Member

Откуда:
Сообщений: 13
Я, конечно, понимаю, что прошло уже почти полтора года со старта топика, но в гугле он (топик) на первом месте по запросу "php слить многомерные массивы", а предложенная функция-то неправильная..

В общем, вот правильный вариант, чтобы народ из поиска бездумно не копировал не правильный вариант:
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;
}
8 апр 13, 07:25    [14149421]     Ответить | Цитировать Сообщить модератору
 Re: слить два многомерных массива  [new]
Карташов Алексей
Member

Откуда:
Сообщений: 13
Даже вот так:
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;
}


Кто может написать лучше - напишите (-:
8 апр 13, 07:39    [14149428]     Ответить | Цитировать Сообщить модератору
 Re: слить два многомерных массива  [new]
ScareCrow
Member

Откуда: Белый город
Сообщений: 15774
предлагаю для начала написать правильно. тоесть так, чтобы хотябы работало.
8 апр 13, 07:46    [14149432]     Ответить | Цитировать Сообщить модератору
 Re: слить два многомерных массива  [new]
Карташов Алексей
Member

Откуда:
Сообщений: 13
ScareCrow, у меня работает - проблем с этим не испытываю)
10 апр 13, 01:39    [14159506]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: слить два многомерных массива  [new]
Виктор Цмшсе
Guest
Карташов Алексей,

не работает! Ошибка! Вот так работает. :)
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;
}
28 окт 16, 18:18    [19835175]     Ответить | Цитировать Сообщить модератору
 Re: слить два многомерных массива  [new]
kalamfur
Member

Откуда: Душанбе
Сообщений: 371
я бы написал так:

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


ЗЫ: Не пинайте , что откопал эту тему, понадобилось слить массивы, думать отвык, чуть что лезу в гугл, а тут это..
28 сен 17, 01:13    [20827957]     Ответить | Цитировать Сообщить модератору
 Re: слить два многомерных массива  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 728
Вообще - то, Пионэр, дал правильный код. Просто слегка ошибся с действием проверки ключа. Надо было Isset проверить первым делом.

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




Результат

Array
(
    [post] => Array
        (
            [3] => Array
                (
                    [title] => Array
                        (
                            [_mess_] => попробуй ещё
                            [_val_] => введите текст
                            [_err_] => WTF!
                        )

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

                )

        )

)
2 окт 17, 10:16    [20835533]     Ответить | Цитировать Сообщить модератору
Все форумы / PHP, Perl, Python Ответить