Задать вопрос
jessepinkman010101
@jessepinkman010101
Варю синий код

Как избегать foreach внутри foreach?

Есть массив
Array
(
    [0] => Array
        (
            [:stock_type] => tests
        )

    [1] => Array
        (
            [stock_name] => test
        )

)

Массив заполняется динамически.
$arr[] = $var;

Что бы получить ключ и значение нужно сделать сделать foreach два раза

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

Каким образом можно сделать это по другому(правильно) ?

spoiler
Это мой третий вопрос на тостере и надеюсь, что, бог действительно любит троицу и хотя бы на этот вопрос я найду решение.
  • Вопрос задан
  • 2073 просмотра
Подписаться 2 Простой 7 комментариев
Решения вопроса 5
index0h
@index0h
PHP, Golang. https://github.com/index0h
Как избегать foreach внутри foreach?

Сделать его не явным

Очень часто вижу на разных форумах, в коммах в вк и тд юзать цикл внутри цикла не правильно

Глупости. Если у вас структура данных - массив массивов даже заюзав какой-нить array_map/array_values/array_keys/array_merge/... вы все равно будете использовать двойной цикл, пусть и не явно. В случае рекурсивного обхода у вас будет точно так же цикл внутри цикла и тоже не явно.

Каким образом можно сделать это по другому(правильно) ?

Написать цикл внутри цикла и не выпендриваться.
Ответ написан
Комментировать
cr1gger
@cr1gger
Все дороги ведут в Рим — встретимся в Риме!
Бред, если контекст задачи требует это, то делай.
К примеру. У нас есть JSON c артистами у каждого из которого есть треки.
$artists = [
            [
                'name' => 'Artist name1',
                'tracks' => [
                    [
                        'track_name' => 'My first song'
                    ],
                    [
                        'track_name' => 'My second song'
                    ]
                ]
            ],
            [
                'name' => 'Artist name1',
                'tracks' => [
                    [
                        'track_name' => 'My first song'
                    ],
                    [
                        'track_name' => 'My second song'
                    ]
                ]
            ],
        ];

Нам нужно собрать все треки всех артистов в один массив
И ты начинаешь перебирать артистов у каждого из которого далее перебираешь треки и заносишь в отдельный массив.

$all_tracks = [];
        foreach($artists as $artist)
        {
            foreach($artist['tracks'] as $track)
            {
                $all_tracks[] = $track['track_name'];
            }
        }
        var_dump($all_tracks);


Но есть и другой более лаконичный вариант решения
$all_tracks = [];
        foreach($artists as $artist)
        {
            $all_tracks = array_merge($all_tracks, array_column($artist['tracks'], 'track_name'));
        }
        var_dump($all_tracks);


Хотя по моему скромному мнению он хуже. Т.к функция array_column внутри себя тоже содержит цикл, и array_merge тоже. И уже не 2, а 3 получилось цикла
Ответ написан
Комментировать
nokimaro
@nokimaro
Меня невозможно остановить, если я смогу начать.
не ужели у вас в практике не было случая, когда нужно было юзать цикл внутри цикла ? Как вы с этим боролись

Каждый день такие случаи, и я никак с этим не борюсь - потому что это не проблема. Проблема это когда вместо понимания сути ориентируешься на
Очень часто вижу на разных форумах, в коммах в вк и тд юзать цикл внутри цикла не правильно


Если хочется понять почему стоит избегать вложенных циклов, то можно почитать, и потом в конкретном своём случае принять решение стоит или не стоит...
https://ru.wikipedia.org/wiki/Временная_сложность_...
https://tproger.ru/articles/computational-complexi...

Ниже решение вопроса без вложенного foreach(), но на вскидку такой код будет не быстрее или равным по скорости для решения с вложенными циклами.
<?php
$arr = [
    0 => ['key1' => 'value1'],
    1 => ['key2' => 'value2'],
    2 => ['key3' => 'value3'],
];

foreach($arr as $data)
{
    $key = array_keys($data)[0];
    $val = $data[$key];
    
    echo "{$key}: {$val}\n";
}

//key1: value1
//key2: value2
//key3: value3
Ответ написан
Комментировать
HighTechLowLife
@HighTechLowLife
1. Если подмассивы имеют одинаковый формат, то можно сделать что-то вроде
$stockNames = array_column($arr, 'stock_name', 'id');

Потом обращаться как echo $stockNames[$stockId] ?? '';

2. Если разный, то смысла в этом нет. Тут только два foreach'a (ну, не будем брать во внимание `array_filter`, `array_map`).
Ответ написан
Комментировать
rozhnev
@rozhnev Куратор тега PHP
Fullstack programmer, DBA, медленно, дорого
Посмотрите, возможно это Вам поможет:
<?php
$input = [
    ['stock_type' => 'tests'],
    ['stock_name' => 'test', 'one_more_key' => 'one_more_value']
];

$result = [];

foreach($input as $i) {
	$result = array_merge($result, $i);
}

var_export($result);


Проверить код РНР здесь
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Очень часто вижу на разных форумах, в коммах в вк и тд юзать цикл внутри цикла не правильно, но как этого избегать никто не пишет, по крайней мере я не нашел.

дак сам у них спроси, потом отпишись здесь в комментах
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы