Как собрать массив массивов, имея массивы ключей, ключей и значений вложенных массивов?

Ссылка скопирована
PHP
1 ответ

Имеются вот такие массивы:

$input = [     '111',     '222', ]; $array1 = [     'new',     'confirmed' ]; $array2 = [     '7777',     'XXXX' ]; $params = [     'state',     'warehouse' ];

$input = [ '111', '222', ]; $array1 = [ 'new', 'confirmed' ]; $array2 = [ '7777', 'XXXX' ]; $params = [ 'state', 'warehouse' ];

Необходимо получить массив:

Array (    [111] => Array                   (                   [state] => 'new'                   [warehouse] => '7777'                   )    [222] => Array                   (                   [state] => 'confirmed'                   [warehouse] => 'XXXX'                   ) )

Array ( [111] => Array ( [state] => 'new' [warehouse] => '7777' ) [222] => Array ( [state] => 'confirmed' [warehouse] => 'XXXX' ) )

Массив $input содержит ключи для элементов первого уровня, их значениями являются подмассивы с ключами из массива $params и к каждому такому ключу задаются по очереди значения из массивов $array1 $array2 и т.д.

Каждый из массивов уже упорядочен, то есть места значений в массивах $input $array1 $array2 относятся к одной сущности, например, если взять второе место, то получается 222(id) + confirmed(статус) + XXXX(имя сущности).

Как оформить цикл формирования описанного массива?

Дополнительно:

Показывайте, как пытались использовать "функцию" foreach

  • подсказка: у этой языковой конструкции вариант синтаксиса с получением смещения
    которое можно использовать при обращении ко всем остальным массивам
  • Ипатьев, на данный момент получилось оформить конструкцию похожую на то что нужно с помощью:
    foreach ($input as &$item) {     $id[] = $item;     $item = $params; }

    foreach ($input as &$item) { $id[] = $item; $item = $params; }

    На выходе получаю

    Array (     [0] => Array         (             [0] => state             [1] => warehouse         )      [1] => Array         (             [0] => state             [1] => warehouse         )      [2] => Array         (             [0] => state             [1] => warehouse         )  )

    Array ( [0] => Array ( [0] => state [1] => warehouse ) [1] => Array ( [0] => state [1] => warehouse ) [2] => Array ( [0] => state [1] => warehouse ) )

    Ключи для первого уровня заранее сохранены в массиве $id и после этого заменяет на подмассив в котором ключи из $params попадают в значения.

    Для того чтобы задать новый массив с ключами и значениями использую:

    for ($i = 0; $i<count($key); $i++) {     $array[$key[$i]] = $value[$i]; }

    for ($i = 0; $i<count($key); $i++) { $array[$key[$i]] = $value[$i]; }

  • перебирайте вот так foreach ($input as $i =>$id {
    и поставляйте в итоговый значения из остальных массивов по ключу $i

    а на код внизу не надо смотреть. он написан для самовыражения

  • вообще соглашусь, для начинающего задачка довольно сложная.
    но полезная
    главная проблема тут в нумерованных массивах
    то есть, чтобы получить полностью динамический код, и при этом не оскоромиться об переменные переменные, надо $array1 и $array2 собрать в отдельный массив, [$array1, $array1] и использовать в коде его.

    для начала можно решить упрощенный вариант, приняв, что в params всегда только 2 элемента

  • $input = [     '111',     '222', ];  $arrays = [     [         'new',         'confirmed'     ],     [         '7777',         'XXXX'     ] ];  $params = [     'state',     'warehouse' ];  $result = [];  for ($i = 0; $i < count($input); $i++) {     $key = $input[$i];     $result[$key] = [];     for ($j = 0; $j < count($params); $j++) {         $result[$key][$params[$j]] = $arrays[$j][$i];     } }  print_r($result);

    $input = [ '111', '222', ]; $arrays = [ [ 'new', 'confirmed' ], [ '7777', 'XXXX' ] ]; $params = [ 'state', 'warehouse' ]; $result = []; for ($i = 0; $i < count($input); $i++) { $key = $input[$i]; $result[$key] = []; for ($j = 0; $j < count($params); $j++) { $result[$key][$params[$j]] = $arrays[$j][$i]; } } print_r($result);

    • foreach все-таки гораздо удобнее, чем for.
      и писать проще, и сам значения переменным присваивает
    • Ипатьев, применил этот блок из ответа и сработало!
      for ($i = 0; $i < count($input); $i++) {     $key = $input[$i];     $result[$key] = [];     for ($j = 0; $j < count($params); $j++) {         $result[$key][$params[$j]] = $arrays[$j][$i];     } }

      for ($i = 0; $i < count($input); $i++) { $key = $input[$i]; $result[$key] = []; for ($j = 0; $j < count($params); $j++) { $result[$key][$params[$j]] = $arrays[$j][$i]; } }

      array1,2 объединил в один. А можете показать как аналог данного запроса выглядит на foreach? Соглашусь что читать его проще чем for но не понимаю как его написать

    • Я же уже показал, в комментарии выше
    • Ипатьев, спасибо, работает!
      foreach ($input as $i => $item) {     $key = $input[$i];     $result[$key] = [];     foreach ($params as $j => $param) {         $result[$key][$params[$j]] = $arrays[$j][$i];     } }

      foreach ($input as $i => $item) { $key = $input[$i]; $result[$key] = []; foreach ($params as $j => $param) { $result[$key][$params[$j]] = $arrays[$j][$i]; } }

    • danilapon, в вашем коде есть ненужные присвоения, выкинув их можно записать так:
      foreach ($input as $i => $key) {     $result[$key] = [];     foreach ($params as $j => $param) {         $result[$key][$param] = $arrays[$j][$i];     } }

      foreach ($input as $i => $key) { $result[$key] = []; foreach ($params as $j => $param) { $result[$key][$param] = $arrays[$j][$i]; } }

      Добавлю, foreach не только удобнее, он и более производительный при обходе массива, чем for.

    • Vitsliputsli, ну это сказки же.
      и у вас тоже ненужные присвоения (:
    • Ипатьев,

      ну это сказки же.
      и у вас тоже ненужные присвоения (:

      Foreach это итератор, он перебирает массив по ссылкам двусвязного списка, в for обращаемся по ключу (конкретно в этом коде, можно было бы и в цикл for добавить итератор, но тогда он еще более бесмыссленым становится), а значит идти придется через хеш-таблицу, а не сразу по прямой ссылке. Лишнее действие будет замедлять работу.
      Если код можно еще улучшить, так покажите, а не кичитесь "тайным знанием".

    • Это не то замедление, о котором вообще стоит говорить.
      Вы его увидите только на цикле, который вообще нихчего не делает. Во всех остальных случаях вы его с электронным микроскопом не увидите.

      Бессмысленность строчки $result[$key] = []; - это для вас "тайное знание"? :)

    • Ипатьев,

      Это не то замедление, о котором вообще стоит говорить.
      Вы его увидите только на цикле, который вообще нихчего не делает. Во всех остальных случаях вы его с электронным микроскопом не увидите.

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

      Бессмысленность строчки $result[$key] = []; - это для вас "тайное знание"? :)

      Да, не вижу как можно без нее обойтись. Покажите?

    • Vitsliputsli

      Есть такое выражение "экономить на спичках", когда мы начинаем оптимизировать то, что и так работает быстро,

      Верно, именно поэтому замечание про "более лучше производительный" не имеет смысла и является скорее вредным, поскольку создает ненужное суеверие.

      для обхода массива нужно использовать итератор

      не нужно.
      нужно использовать то, что подходит для конкретной задачи
      если я, к примеру, хочу изменять значения массива и при этом видеть изменения сразу, то нужно использовать обращение по ключу.

      не вижу

      ну если так не видите, то просто уберите её из кода, и запустите его :)

    • Ипатьев,

      Верно, именно поэтому замечание про "более лучше производительный" не имеет смысла и является скорее вредным, поскольку создает классическое суеверие.

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

      не нужно.
      нужно использовать то, что подходит для конкретной задачи
      если я, к примеру, хочу изменять значения массива и при этом видеть изменения сразу, то нужно использовать обращение по ключу.

      Да, прочитайте наконец про итераторы! С чего вы взяли, что для изменения нужно обращаться по ключу? У вас курсор указывает на конкретный бакет, берите и меняйте, если надо.

      ну если так не видите, то просто уберите её из кода, и запустите его :)

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

    • чтобы увидеть, что код работает неэффективно.

      Разницу между for и foreach я никогда не увижу. Но не буду спорить. С сектантами веры экономии на спичках рациональные доводы не действуют.

      С чего вы взяли, что для изменения нужно обращаться по ключу?

      Читайте внимательнее. Мне надо не для изменения. А для изменения, которое видно в массиве сразу, а не по окончании перебора.

      инициализация должна быть явной.

      Разумеется должна быть. Она там и есть. А эта строчка лишняя.

    • Ипатьев,

      Читайте внимательнее. Мне надо не для изменения. А для изменения, которое видно сразу, на по окончании перебора.

      Что значит "сразу", а не по "окончании перебора"? Вы изменили значение, как оно у вас "не сразу" будет видно? У нас же не транзакции. Вы бы хоть код привели, что имеете ввиду, а то все вытягивать нужно.

      Разумеется должна быть. Она там и есть. А эта строчка лишняя.

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

    • Вы бы хоть код привели

      https://3v4l.org/i5RPC

      Если в неинициализированной переменной

      Переменная инициализирована.
      $result = []; там стоит перед циклом, где и положено. больше никакие инициализации тут не нужны

    • Ипатьев,

      https://3v4l.org/i5RPC

      передавайте в переменную не значение, а ссылку:

      foreach ($array as $i => &$v) {     if ($i === 0) {         $array[1] = 3;     }     echo "$i: $vn"; }

      foreach ($array as $i => &$v) { if ($i === 0) { $array[1] = 3; } echo "$i: $vn"; }

      Переменная инициализирована.

      Эт понятно, только вот у вас не примитивный тип, а структура. И все эти вложенные массивы в структуре - отдельные zval, а то что мы явно не выделили имя переменной особо значения не имеет.
      Почему нужно я выше написал, если вы не считаете неявные манипуляции вердными, я переубеждать не буду.

    • передавайте в переменную не значение, а ссылку

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

      неявные манипуляции

      там нет неявных манипуляций.
      $result[$key][$param] = $arrays[$j][$i]; - это точно такое же явное присвоение.

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

    • Ипатьев,

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

      Так забавно с вами что-либо обсуждать, никакой аргументации, только бессмысленные "бред", "догма", "мне не нужно", "только так правильно" и т.п. Нет ничего зазорного признать, что чего-то не знаешь.
      Вообще то нужна ссылка, очевидно, что изменение другой переменной, не изменит первоначальную, если передавать не по ссылке.

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

      Ммм, переход на личности, думаете, так сможете спрятаться, не получится.
      Еще как есть, когда вы создаете массив внутри массива, будет создан новый zval массива, это совсем другой массив, с новой хеш-таблицей и новым списком. То что вам кажется, что оно "както само", нет, это не так. Поэтому, хотя ваши заявления "в большинстве случаев работают" (на самом деле только в примитивных ситуациях), у вас отсутствует "реальное понимание" как это работает, и будет ли вообще работать в более менее сложных ситуациях.

    Ответы:

    function combine($ids, $keys, ...$values) {   return array_combine(     $ids,     array_map(       fn($i) => array_combine($keys, array_column($values, $i)),       array_keys($ids)     )   ); }   $result = combine($input, $params, $array1, $array2);

    function combine($ids, $keys, ...$values) { return array_combine( $ids, array_map( fn($i) => array_combine($keys, array_column($values, $i)), array_keys($ids) ) ); } $result = combine($input, $params, $array1, $array2);

    • тот случай, когда конвенциональное решение получается тупо проще выпендрёжно-нечитабельного :)
    • Чтобы понять что такое рекурсия - нужно понять что такое рекурсия
    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Игорь Волков Ответ

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

    Пример кода на PHP:

    // Массивы ключей и значений вложенных массивов
    $keys = array('key1', 'key2', 'key3');
    $values = array('value1', 'value2', 'value3');
     
    // Инициализация пустого массива для хранения результирующих массивов
    $result = array();
     
    // Цикл по массиву ключей
    foreach ($keys as $key) {
        // Создание нового массива с ключем из массива ключей и значением из массива значений
        $newArray = array($key => array_shift($values));
     
        // Добавление нового массива в результирующий массив
        $result[] = $newArray;
    }
     
    // Вывод результирующего массива
    print_r($result);

    // Массивы ключей и значений вложенных массивов $keys = array('key1', 'key2', 'key3'); $values = array('value1', 'value2', 'value3'); // Инициализация пустого массива для хранения результирующих массивов $result = array(); // Цикл по массиву ключей foreach ($keys as $key) { // Создание нового массива с ключем из массива ключей и значением из массива значений $newArray = array($key => array_shift($values)); // Добавление нового массива в результирующий массив $result[] = $newArray; } // Вывод результирующего массива print_r($result);

    В данном примере мы используем цикл foreach для перебора массива ключей и создания новых массивов с соответствующими ключами и значениями из другого массива. Затем эти новые массивы добавляются в результирующий массив. В итоге мы получаем массив массивов, как требуется в задании.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно