Динамическое добавление пустого индекса в массив на основе индексов по умолчанию

#php #arrays #laravel

#php #массивы #laravel

Вопрос:

У меня есть приведенный ниже массив, который включает набор индексов по умолчанию, которые должны присутствовать в моем конечном массиве:

 'entities' => [
        'deliveredAt',
        'issuedAt',
        'totals' => [
            'due',
            'gross',
            'net',
            'tax' => [
                'amount',
                'net',
                'rate',
            ],
        ]
],
  

Приведенный выше массив сохраняется в переменной с именем $entities .

Теперь у меня есть сторонний API, который вернет вышеупомянутые объекты, но включит их в ответ только в том случае, если объект содержит значение.

Например, $response может выглядеть следующим образом:

 array:2 [▼
  "issuedAt" => "2020-08-20"
  "totals" => array:1 [▼
    "tax" => []
  ]
]
  

Как вы можете видеть, при сравнении возвращаемого массива с ожидаемыми индексами, нескольких не хватает:

  • deliveredAt
  • totals.due , totals.gross , totals.net , totals.tax.amount , totals.tax.net , totals.tax.rate

Я пытаюсь создать метод, который может выполнять итерации по $response массиву и проверять, содержит ли он индексы, которые я ожидаю. Если нет, я просто хочу установить индекс со значением null .

Ниже то, что у меня есть на данный момент:

 foreach ($entities as $key => $entity) {
         if (!is_array($entity)) {
             if (!isset($response[$entity])) {
                    $response[$entity] = null;
             }
         }
}
  

Однако это добавит только индекс, который не является массивом. В этом примере будет добавлено только: deliveredAt => null .

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

Комментарии:

1. И если tax не указано — должно ли это быть tax => null , или tax => [amount => null etc ] ?

2. @u_mulder это должно быть tax => ['amount' => null, 'net' => null, 'rate' => null]

Ответ №1:

Вы можете определить исходный массив с помощью ключей и NULL (или чего угодно, что вам нужно) в качестве значений:

 $entities = [
    'deliveredAt' => null,
    'issuedAt' => null,
    'totals' => [
        'due' => null,
        'gross' => null,
        'net' => null,
        'tax' => [
            'amount' => null,
            'net' => null,
            'rate' => null,
        ],
    ]
];

// here's your real data
$realData = [
  "issuedAt" => "2020-08-20",
  "totals" => [
    "tax" => [
      'net' => 42,    
    ]
  ]
];
// now use array_replace_recursive to replace keys in `$entities` with values of `$realData`
print_r(array_replace_recursive($entities, $realData));
  

Скрипка.

Также обратите внимание, что ключи из $realData , которые не существуют в $entities , будут добавлены к результату.

Ответ №2:

Для этого вы можете использовать array_replace_recursive. Вам нужно было только немного изменить ваши ассоциативные объекты массива, поэтому каждому свойству требуется инициализация (например, NULL или «).

 $result = array_replace_recursive($entities, $array);
  

Здесь вы можете протестировать этоhttp://sandbox.onlinephpfunctions.com/code/4688ed3240050479edeef7c9e4da16f98dbe01de

Вот код отверстия:

 $array = [
  "issuedAt" => "2020-08-20",
  "totals" => [
    "tax" => [
        'amount' => 100
    ]
  ]
];

$entities = [
    'deliveredAt' => NULL,
    'issuedAt' => NULL,
    'totals' => [
        'due' => NULL,
        'gross' => NULL,
        'net' => NULL,
        'tax' => [
            'amount' => NULL,
            'net' => NULL,
            'rate' => NULL
        ],
    ]
];

$result = array_replace_recursive($entities, $array);
var_dump($result);
  

Комментарии:

1. И в чем разница с моим ответом?

2. Вы правы. Тем временем я был в 1 часе езды и не видел вашего ответа, поскольку я завершил свой ответ и опубликовал его. Ставлю вам 1 балл.