Форум программистов, компьютерный форум, киберфорум
PHP для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
2 / 2 / 1
Регистрация: 10.05.2016
Сообщений: 61
1

Как разобрать многомерный массив и пересобрать его в нужном виде?

25.02.2020, 18:33. Показов 714. Ответов 5

Добрый день.

Подскажите пожалуйста по такой проблеме:

Имеется JSON:

JSON
1
2
3
4
5
6
7
8
9
10
11
12
string(1514) "{
"business_name":["Название компании 1","Название компании 2","Название компании 3"],
"business_address":["Улица 156, Город, Область, 11111","Улица 157, Город, Область, 11111","Улица 158, Город, Область, 11111"],
"business_logo":["https://www.cyberforum.ru/images/headers/maple.jpg","https://www.cyberforum.ru/images/sampledata/parks/banner_cradle.jpg","https://www.cyberforum.ru/images/banners/shop-ad-books.jpg"],
"business_phone":["+12345678910","+12345678911","+12345678912"],
"business_email":["example1@gmail.com","example2@gmail.com","example3@gmail.com"],
"business_site":["https://example1.com","https://example2.com","https://example3.com"],
"business_bdays":["Понедельник, Вторник, Среда, Четверг, Пятница, Суббота, Воскресенье","Понедельник, Вторник, Среда, Четверг, Пятница, Суббота, Воскресенье","Понедельник, Вторник, Среда, Четверг, Пятница, Суббота, Воскресенье"],
"business_bdays_short":["Пн, Вт, Ср, Чт, Пт, Сб, Вс","Пн, Вт, Ср, Чт, Пт, Сб, Вс","Пн, Вт, Ср, Чт, Пт, Сб, Вс"],
"business_hours":["08:00-21:00","08:00-21:00","08:00-21:00"],
"business_payments_type":["кредитная карта, наличные","кредитная карта, наличные","кредитная карта, наличные"],
"business_price_range":["от $100","от $200","от $300"]}"
Который с помощью json_decode($var, true) благополучно преобразовывается в очень многомерный массив (назовем его "изначальный"):

PHP
1
2
3
4
5
6
7
8
9
10
11
array(11) { 
["business_name"]=> array(3) { [0]=> string(35) "Название компании 1" [1]=> string(35) "Название компании 2" [2]=> string(35) "Название компании 3" } 
["business_address"]=> array(3) { [0]=> string(49) "Улица 156, Город, Область, 11111" [1]=> string(49) "Улица 157, Город, Область, 11111" [2]=> string(49) "Улица 158, Город, Область, 11111" } 
["business_logo"]=> array(3) { [0]=> string(24) "https://www.cyberforum.ru/images/headers/maple.jpg" [1]=> string(41) "https://www.cyberforum.ru/images/sampledata/parks/banner_cradle.jpg" [2]=> string(32) "https://www.cyberforum.ru/images/banners/shop-ad-books.jpg" } 
["business_phone"]=> array(3) { [0]=> string(12) "+12345678910" [1]=> string(12) "+12345678911" [2]=> string(12) "+12345678912" } 
["business_email"]=> array(3) { [0]=> string(18) "example1@gmail.com" [1]=> string(18) "example2@gmail.com" [2]=> string(18) "example3@gmail.com" } 
["business_site"]=> array(3) { [0]=> string(20) "https://example1.com" [1]=> string(20) "https://example2.com" [2]=> string(20) "https://example3.com" } 
["business_bdays"]=> array(3) { [0]=> string(122) "Понедельник, Вторник, Среда, Четверг, Пятница, Суббота, Воскресенье" [1]=> string(122) "Понедельник, Вторник, Среда, Четверг, Пятница, Суббота, Воскресенье" [2]=> string(122) "Понедельник, Вторник, Среда, Четверг, Пятница, Суббота, Воскресенье" } 
["business_bdays_short"]=> array(3) { [0]=> string(40) "Пн, Вт, Ср, Чт, Пт, Сб, Вс" [1]=> string(40) "Пн, Вт, Ср, Чт, Пт, Сб, Вс" [2]=> string(40) "Пн, Вт, Ср, Чт, Пт, Сб, Вс" } 
["business_hours"]=> array(3) { [0]=> string(11) "08:00-21:00" [1]=> string(11) "08:00-21:00" [2]=> string(11) "08:00-21:00" } ["business_payments_type"]=> array(3) { [0]=> string(47) "кредитная карта, наличные" [1]=> string(47) "кредитная карта, наличные" [2]=> string(47) "кредитная карта, наличные" } 
["business_price_range"]=> array(3) { [0]=> string(9) "от $100" [1]=> string(9) "от $200" [2]=> string(9) "от $300" } }
Необходимо перетрясти изначальный массив, чтобы на выходе получить другой многомерный массив (на значения ключей в массивах ниже не обращайте внимания - они не используются по факту):

PHP
1
2
3
4
5
array(3) { 
 
["local-business0"]=> array(11) { ["Название организации"]=> string(35) "Название компании 1" ["Адрес отделения (через запятую в формате адрес с номером дома, город, область, почтовый код)"]=> string(49) "Улица 156, Город, Область, 11111" ["Логотип"]=> string(41) "https://www.cyberforum.ru/images/sampledata/fruitshop/bananas_2.jpg" ["Контактный телефон"]=> string(12) "+12345678910" ["Адрес электронной почты"]=> string(18) "example1@gmail.com" ["Сайт в интернете"]=> string(20) "https://example1.com" ["Рабочие дни (полные названия через запятую)"]=> string(122) "Понедельник, Вторник, Среда, Четверг, Пятница, Суббота, Воскресенье" ["Рабочие дни (сокращенные названия через запятую)"]=> string(40) "Пн, Вт, Ср, Чт, Пт, Сб, Вс" ["Рабочее время (через дефис в 24-часовом формате)"]=> string(11) "08:00-21:00" ["Способы оплаты услуг"]=> string(84) "кредитная карта, наличные, банковский перевод" ["Ценовой диапазон"]=> string(9) "от 100$" } 
["local-business1"]=> array(11) { ["Название организации"]=> string(35) "Название компании 2" ["Адрес отделения (через запятую в формате адрес с номером дома, город, область, почтовый код)"]=> string(49) "Улица 157, Город, Область, 11111" ["Логотип"]=> string(29) "https://www.cyberforum.ru/images/banners/osmbanner2.png" ["Контактный телефон"]=> string(12) "+12345678911" ["Адрес электронной почты"]=> string(27) "example2@gmail.com@gmailcom" ["Сайт в интернете"]=> string(20) "https://example2.com" ["Рабочие дни (полные названия через запятую)"]=> string(122) "Понедельник, Вторник, Среда, Четверг, Пятница, Суббота, Воскресенье" ["Рабочие дни (сокращенные названия через запятую)"]=> string(40) "Пн, Вт, Ср, Чт, Пт, Сб, Вс" ["Рабочее время (через дефис в 24-часовом формате)"]=> string(11) "08:00-21:00" ["Способы оплаты услуг"]=> string(84) "кредитная карта, наличные, банковский перевод" ["Ценовой диапазон"]=> string(9) "от 200$" } 
["local-business2"]=> array(11) { ["Название организации"]=> string(35) "Название компании 3" ["Адрес отделения (через запятую в формате адрес с номером дома, город, область, почтовый код)"]=> string(49) "Улица 158, Город, Область, 11111" ["Логотип"]=> string(24) "https://www.cyberforum.ru/images/headers/maple.jpg" ["Контактный телефон"]=> string(11) "+1234567812" ["Адрес электронной почты"]=> string(18) "example3@gmail.com" ["Сайт в интернете"]=> string(20) "https://example3.com" ["Рабочие дни (полные названия через запятую)"]=> string(122) "Понедельник, Вторник, Среда, Четверг, Пятница, Суббота, Воскресенье" ["Рабочие дни (сокращенные названия через запятую)"]=> string(40) "Пн, Вт, Ср, Чт, Пт, Сб, Вс" ["Рабочее время (через дефис в 24-часовом формате)"]=> string(11) "08:00-21:00" ["Способы оплаты услуг"]=> string(84) "кредитная карта, наличные, банковский перевод" ["Ценовой диапазон"]=> string(9) "от 300$" } }
Однако, я никак не могу уловить правильный путь разбора изначального массива, чтобы не писать монструозный код, похожий на один огромный костыль с последующей пересборкой его в массив, описанный выше.

Возможно, кто-то сталкивался с такой ситуации и может подсказать хотя бы вектор движения.

Спасибо!
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.02.2020, 18:33
Ответы с готовыми решениями:

Как разобрать многомерный массив?
Привет вот есть такой массив как его разобрать? я пытаюсь так но он не все уровни...

Разобрать многомерный массив и вывести
Добрый день. Раньше все было просто input_initial_value = $(this).val(); //...

Как инициализировать многомерный массив в общем виде?
как инициализировать многомерный массив в общем виде? есть файл, в котором присутствуют вхождения...

Как объявить многомерный массив и сразу инициализировать его?
Методом проб выяснил, что объявить и сразу проинициализировать многомерный массив можно так (пример...

5
1423 / 956 / 505
Регистрация: 23.08.2015
Сообщений: 2,476
25.02.2020, 18:54 2
Drezor,
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
$arr = [
    'business_name' => ['Название компании 1', 'Название компании 2', 'Название компании 3'],
    'business_address' => ['Улица 156, Город, Область, 11111', 'Улица 157, Город, Область, 11111', 'Улица 158, Город, Область, 11111'],
];
 
$result = [];
 
foreach($arr as $k => $values) {
    foreach($values as $i => $value) {
        $result[$i][$k] = $value;
    }
}
 
var_dump($result);
 
/*
array(3) {
  [0]=>
  array(2) {
    ["business_name"]=>
    string(35) "Название компании 1"
    ["business_address"]=>
    string(49) "Улица 156, Город, Область, 11111"
  }
  [1]=>
  array(2) {
    ["business_name"]=>
    string(35) "Название компании 2"
    ["business_address"]=>
    string(49) "Улица 157, Город, Область, 11111"
  }
  [2]=>
  array(2) {
    ["business_name"]=>
    string(35) "Название компании 3"
    ["business_address"]=>
    string(49) "Улица 158, Город, Область, 11111"
  }
}
*/
1
2 / 2 / 1
Регистрация: 10.05.2016
Сообщений: 61
25.02.2020, 20:31  [ТС] 3
Блин, как я не старался избежать двойного foreach'a, а прописать это все в более изящной форме, с живым рабочим примером я спорить не могу... Разве что инкапсулирую этот foreach в foreach'e и запраторю куда-то в самый низ класса, чтобы глаза не резало - на этом вся изящность и закончится

sad67man, спасибо большое за ответ!
0
1 / 1 / 0
Регистрация: 25.02.2020
Сообщений: 2
25.02.2020, 20:58 4
Попробуй через while со смещением указателя на массив и сбросом при нахождении элемента по условию. Достаточно типовой обход если на вход не структурированные данные подаются. Или через for, но с условием выхода и, возможно счетчиком, внутри цикла. Ну и рекурсия, возможно, решит проблемы, хотя с ней аккуратно тоже надо, расход памяти достаточно немаленький
1
1423 / 956 / 505
Регистрация: 23.08.2015
Сообщений: 2,476
25.02.2020, 22:02 5
Drezor,
Цитата Сообщение от Drezor Посмотреть сообщение
Разве что инкапсулирую этот foreach в foreach'e и запраторю куда-то в самый низ класса, чтобы глаза не резало - на этом вся изящность и закончится
Для этого низкоуровневый код принято выносить в отдельные классы-службы, используя композицию. Таким образом мы можем их даже использовать повторно в других классах)

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Parser
{
    public function parse($json): array
    {
        $data = json_decode($json, true);
        
        $result = [];
 
        foreach($data as $k => $values) {
            foreach($values as $i => $value) {
                $result[$i][$k] = $value;
            }
        }
        
        return $result;
    }
}
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Service
{
    private $parser;
    
    public function __construct(Parser $parser): array
    {
        $this->parser = $parser;
    }
    
    public function doSomething() 
    {
        $json = $this->getJson();
        $arr = $this->parser->parse($json);
    }
}
Вынесли в отдельную службу и получили изящный код) Не захламляя наш основной класс приватными низкоуровневыми методами. А внутри службы можно развернуться на полную) И не пытаться лепить всю логику в пару строчек)
1
2 / 2 / 1
Регистрация: 10.05.2016
Сообщений: 61
28.02.2020, 00:04  [ТС] 6
Цитата Сообщение от dlvwdev Посмотреть сообщение
Попробуй через while со смещением указателя на массив и сбросом при нахождении элемента по условию. Достаточно типовой обход если на вход не структурированные данные подаются. Или через for, но с условием выхода и, возможно счетчиком, внутри цикла. Ну и рекурсия, возможно, решит проблемы, хотя с ней аккуратно тоже надо, расход памяти достаточно немаленький
В том-то и дело, что у меня не может быть условия сброса, потому количество элементов второго уровня не нормированы. В том же массиве [business_name] может оказаться от одного до бесконечности элементов - я просто не буду физически знать когда остановиться.

Но за наводку на подход спасибо - приму к сведению!

Добавлено через 8 минут
Цитата Сообщение от sad67man Посмотреть сообщение
Drezor,

Для этого низкоуровневый код принято выносить в отдельные классы-службы, используя композицию. Таким образом мы можем их даже использовать повторно в других классах)

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Parser
{
    public function parse($json): array
    {
        $data = json_decode($json, true);
        
        $result = [];
 
        foreach($data as $k => $values) {
            foreach($values as $i => $value) {
                $result[$i][$k] = $value;
            }
        }
        
        return $result;
    }
}
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Service
{
    private $parser;
    
    public function __construct(Parser $parser): array
    {
        $this->parser = $parser;
    }
    
    public function doSomething() 
    {
        $json = $this->getJson();
        $arr = $this->parser->parse($json);
    }
}
Вынесли в отдельную службу и получили изящный код) Не захламляя наш основной класс приватными низкоуровневыми методами. А внутри службы можно развернуться на полную) И не пытаться лепить всю логику в пару строчек)
Спасибо за подсказку как это все можно облагородить - в будущем 100 пудов пригодится, однако сейчас я этого не делал, потому что во всем классе буквально 5 методов (не считая конструктора) и это класс для плагина Joomla: работа проходит в одном методе, где вызывается буквально 3 метода для формирования массива в зависимости от параметров плагина и четвертый эксплодит некоторые значиния уже на финальной стадии.

Я это к тому, что в данном случае усложнять, хоть и не существенно, копание в этом классе не столь необходимо: любой кто умеет в понимание $this у РНР класса сразу сориентируется, что нужно искать внутри и не лезть куда-то еще, а РНР доки не дадут утонуть в коде, визуально его разлепляя
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.02.2020, 00:04

Как создать многомерный массив с ключом и заполнить его?
Доброго времени суток!! Помогите мне разобраться как составить много мерный массив То что я хочу...

Массив и как его разобрать
Добры день! Ребята подскажите! В общем делаю запрос получаю XML вот его пытаюсь спарсить но нечего...

Как пересобрать массив
Доброго дня. Помогите разобраться - есть следующие массивы: 1. productidsArray ( =>...

Как вывести в нужном виде?
Всем привет. Есть такой код: <?php $aa = array(0.322, 0.277, 0.110, 0.060, 0.741); // продукт1...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.