Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Как в PHP создать многомерный массив из строки по разделителю? / 20 сообщений из 20, страница 1 из 1
28.02.2013, 13:40
    #38169478
Shitbox2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
Массив A имеет вид:
Код: php
1.
array("aa_bb_cc" => 123, "dd_ee" => 456, ...)


Нужно превратить его в массив B вида:
Код: php
1.
array("aa" => array("bb" => array("cc" => 123))), "dd"=>array("ee" => 456), ...)


Уровней вложенности может быть сколько угодно, разделитель только "_"

Нужно изящное решение. Свое попозже опубликую)
...
Рейтинг: 0 / 0
28.02.2013, 13:50
    #38169520
Ренат
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
Навскидку - не проверял на работоспособность.
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
$result = array();
$data = array("aa_bb_cc" => 123, "dd_ee" => 456);
foreach ($data as $key => $value) {
foreach (array_reverse(explode('_', $key)) as $index) {
$value = array($index => $value);
}
$result = array_merge($result, $value);
}
...
Рейтинг: 0 / 0
28.02.2013, 13:59
    #38169545
skyANA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
Да сама документация по explode может навести на решение
...
Рейтинг: 0 / 0
28.02.2013, 14:37
    #38169641
Програмёр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
Могу ошибаться, но вариант Рената расчитан только на приведённый вариант (что тоже правильно), если же массив будет типа
Код: php
1.
array("aa_bb_cc" => 123, "aa_dd_ee" => 456, ...)


на выходе получим
Код: php
1.
array("aa" => array("dd" => array("ee" => ))), ...)


другими словами первый массив с ключём "aa" будет перезаписан вторым. Кстати, на работоспособность не проверял тоже ))

Предлагаю такой вариант:
Код: 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.
$arr = array(/*входные данные*/);
$res = array();

recorsiveExplode($arr, $res);

function recursiveExplode($arr, &$res){
  $mainLinker = &$res;
  $linker = &$res;
  foreach($arr as $key=>$value){
    $linker = &$mainLinker;
    $newKeys = explode("_", $key);
    foreach($newKeys as $newKey){
      if(!isset($linker[$newKey])){
        $linker[$newKey] = array();
      }
      $linker = &$linker[$newKey];
    }
    if (!is_array($value)){
      $linker = $value;
    }else{
      recursiveExplode($value, $linker);
    }
  }
}



проверена и может обрабатывать даже вложенные массивы типа array("aa_bb_cc" => 123, "aa_dd_ee" => array("aa_dd"=>456)) и на выходе получаем
Код: php
1.
array(1) { ["aa"]=> array(2) { ["bb"]=> array(1) { ["cc"]=> int(123) } ["dd"]=> array(1) { ["ee"]=> array(1) { ["aa"]=> array(1) { ["dd"]=> int(456) } } } } }
...
Рейтинг: 0 / 0
28.02.2013, 16:36
    #38169868
Shitbox2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
автордругими словами первый массив с ключём "aa" будет перезаписан вторым. Кстати, на работоспособность не проверял тоже ))Не-не, так не пойдет, ничего перезаписываться не должно :)

Мой вариант был такой
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
$A = array("aa_bb_cc" => 123, "dd_ee" => 456);
    
foreach ($A as $field => $value) {
        $arr = explode("_", $field);
        $str = '$B';
        for ($i = 0; $i < count($arr); $i++) {
            $str .= '[$arr[' . $i . ']]';
        }
        $str .= "='" . $value . "';";
        eval($str);
}
echo print_r ($B, true);



Единственный минус в нем, что $value = null преобразуется в пустую строку. В моем случае неприятный эффект. Как от него избавиться не придумал пока...

Надеюсь, в ветке предложат более изящные решения)
...
Рейтинг: 0 / 0
28.02.2013, 17:24
    #38169950
Ренат
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
Shitbox2,

ай яй яй, eval как нехорошо... меня всегда учили что это ужасно, но Yii его юзает вовсю - так что нынче даже не поймешь...
...
Рейтинг: 0 / 0
28.02.2013, 17:28
    #38169963
Ренат
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
Shitbox2,


С вашего позволения использую ваш метод и пределаю его:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
$A = array("aa_bb_cc" => 123, "dd_ee" => 456);

$str = '$B=array();';    
foreach ($A as $field => $value) {
        $str .= '$B["'.str_replace('_','"]["', $field).'"]='.var_export($value,1).';';
}
eval($str);
echo print_r ($B, true);



итого имеем: null сохраняеться и array("aa_bb_cc" => 123, "aa_bb_ee" => 456); нормально смерджиться а не перепишеться)
...
Рейтинг: 0 / 0
28.02.2013, 17:41
    #38169988
Shitbox2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
О! Так значительно лучше!
...
Рейтинг: 0 / 0
28.02.2013, 18:00
    #38170018
Shitbox2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
Выдает Warning: Cannot use a scalar value as an array in ... : eval()'d code on line 1 если в ключе нет разделителя "_" т.е. array("aa" => 123, "dd_ee" => 456, ...) не обработается полностью
...
Рейтинг: 0 / 0
01.03.2013, 06:01
    #38170438
r u
r u
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
eval зло. это тормозно и небезопасно. тем более когда можно решить задачу "более лучше"(с)
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
$result = array();
$data = array("aa_bb_cc" => 123, "aa_bb_ee" => 456, "dd_ee" => 789);
foreach ($data as $k=>$v) {
    $ref =& $result;
    foreach(explode('_',$k) as $vv) {
        if (!isset($ref[$vv]))
            $ref[$vv]=array();
        $ref =& $ref[$vv];
    }
    $ref=$v;
}
...
Рейтинг: 0 / 0
01.03.2013, 10:37
    #38170598
Ренат
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
r u,

кароче пока представлены три решения:
1. через eval
2. через explode и все
3. через explode & ссылки

кто нить что нить еще придумает?
...
Рейтинг: 0 / 0
03.03.2013, 23:49
    #38172764
Как в PHP создать многомерный массив из строки по разделителю?
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
$arr = array("aa_bb_cc" => 123, "dd_ee" => 2452);
$nArr = array();
foreach($arr as $index=>$value) {	
	foreach(array_reverse(explode('_', $index)) as $i) {	
		$value = array($i=>$value);
	}
	$nArr=array_merge($nArr, $value);
}
print_r($nArr);
...
Рейтинг: 0 / 0
04.03.2013, 20:46
    #38173842
Ренат
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
Михаил Зеленый,

А чем от моего варианта 13993806 отличаеться? именами переменных?)
...
Рейтинг: 0 / 0
05.03.2013, 05:34
    #38174070
r u
r u
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
РенатА чем от моего варианта 13993806 отличаеться? именами переменных?)
я тоже непонял ))
...
Рейтинг: 0 / 0
05.03.2013, 10:13
    #38174193
Как в PHP создать многомерный массив из строки по разделителю?
Ренат,

Да действительно =) Прошу прощения, я мельком пробежался. Видимо мы одинаково мыслим)
...
Рейтинг: 0 / 0
06.03.2013, 16:11
    #38176244
Shitbox2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
Да, другие способы чего-то не придумываются. С ссылками наиболее правильный, думаю.
...
Рейтинг: 0 / 0
06.03.2013, 16:36
    #38176286
Shitbox2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
Теперь бьюсь над расширением задачи. Возьмем этот вариант
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
   function arraySep2dim(array $in, $separator = '_') {
        $result = array();
        foreach ($in as $key => $value) {
            $ptr = &$result;
            foreach (explode($separator, $key) as $token) {
                $ptr = &$ptr[$token];
            }
            $ptr = is_array($value) ? arraySep2dim($value, $separator) : $value;
        }
        return $result;
    }



Нужно превратить его в функцию
Код: php
1.
arraySep2dim(array $in, $separator = '_$' ,$filter) { ... }


где $filter — проходящее значение в подмассиве. К примеру, без фильтра имеем на выходе
Код: php
1.
array("aa" => array("bb" => array("cc" => 149), "cc" => 123, "dd" => array("ee" => 456, "ff" => 789)))


если $filter = "bb", то на выходе получаем
Код: php
1.
array("aa" => array("cc" => 149))


если $filter = "сс", то на выходе получаем
Код: php
1.
array("aa" => 123)


если $filter = "ff", то на выходе получаем
Код: sql
1.
array("aa" => array("bb" => array("cc" => 149), "cc" => 123, "dd" => 789))


Т.е. значение в подмассиве, совпадающее с фильтром становится значением родителя, а остальные удаляются
...
Рейтинг: 0 / 0
06.03.2013, 17:21
    #38176390
Shitbox2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
P.S. r u, в случае
Код: php
1.
array( 'A' => "", 'bb_B1' => "", 'bb_B2' => "абв", 'cc_C1' => null),'_','B1')


твой код возвращает
Код: php
1.
array(3) { ["A"]=> string(0) "" ["bb"]=> array(2) { ["B1"]=> string(0) "" ["B2"]=> string(6) "абв" } ["cc"]=> array(1) { ["C1"]=> &NULL } }


&NULL вместо NULL, вообще, указатель на любое последнее значение вместо самого значения
...
Рейтинг: 0 / 0
06.03.2013, 19:43
    #38176582
Shitbox2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
Опять же мое решение:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
function arraySep2dim(array $in, $separator = '_', $filter) {
    $result = array();
    $filtered = array();
    foreach ($in as $key => $value) {
        $ptr = &$result;
        foreach (explode($separator, $key) as $k => $token) {
            if (in_array($token, $filtered)) continue 2;
            if ($k == 0 || $token != $filter) {
                $ptr = &$ptr[$token];
                $parent = $token;
            } else {
                $filtered[] = $parent;
                break;
           }
        }
        $ptr = $value;
    }
    return $result;
}
var_dump(arraySep2dim(array( 'A' => "", 'bb_B1_r' => "aa", 'bb_B2_s' => "абв", 'bb_B3_d' => "бб", 'cc_C1_g' => null),'_','B2'));


К сожалению, немного не по той логике. В данном примере вместо 'bb_B1_r', 'bb_B2_s', 'bb_B3_d' запишется 'bb' => "абв", а должно 'bb' => array('s' => "абв"). Т.е. все внутренние массивы разрушается до последнего значения.Есть работающие решения?
...
Рейтинг: 0 / 0
07.03.2013, 05:35
    #38176834
r u
r u
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в PHP создать многомерный массив из строки по разделителю?
Shitbox2Есть работающие решения?
есть. направления решений тебе привели.
думай и дорабатывай.
...
Рейтинг: 0 / 0
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Как в PHP создать многомерный массив из строки по разделителю? / 20 сообщений из 20, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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