Сопоставить ассоциативный массив с другим массивом php - PullRequest
0 голосов
/ 09 января 2020

У меня есть ассоциативный массив состояний какой-либо страны, и названия штатов являются ключами:

array:13 [
  "Ontario" => null
  "Manitoba" => null
  "New Brunswick" => null
  "Yukon" => null
  "Saskatchewan" => null
  "Prince Edward Island" => null
  "Alberta" => null
  "Quebec" => null
  "Nova Scotia" => null
  "British Columbia" => null
  "Nunavut" => null
  "Newfoundland and Labrador" => null
  "Northwest Territories" => null
] 

И у меня есть другой ассоциативный массив, который содержит все состояния, которые имеют значения:

array:8 [
  "Alberta" => 17
  "Cairo" => 1
  "Calgary" => 1
  "ddd" => 4
  "gfdxf" => 1
  "New Cairo" => 1
  "Ontario" => 1
  "secret" => 30
] 

Теперь мне нужно сопоставить второй массив с первым, чтобы результат был:

array:13 [
  "Ontario" => 1
  "Manitoba" => 0
  "New Brunswick" => 0
  "Yukon" => 0
  "Saskatchewan" => 0
  "Prince Edward Island" => 0
  "Alberta" => 17
  "Quebec" => 0
  "Nova Scotia" => 0
  "British Columbia" => 0
  "Nunavut" => 0
  "Newfoundland and Labrador" => 0
  "Northwest Territories" => 0
] 

Я создал вложенный l oop, и он работает нормально, но код очень уродливо, теперь есть ли более эффективный способ сделать это?

Мой код:

foreach ($all_states as $state_x => $value_x) {

    foreach ($country_states as $state_y => &$value_y) {

        if (strtolower($state_x) == strtolower($state_y)) {

            $value_y = $value_x;
        } elseif ($value_y == NULL) {

            $value_y = 0;
        }
    }
}

Ответы [ 4 ]

2 голосов
/ 09 января 2020

Это можно сделать проще с 1 foreach l oop как:

$countriesArr = .... // consider this the array with NULL
$countriesDataArr = ... // consider this to be the array with the values 

foreach( $countriesArr as $k => &$v) {
    $v = isset($countriesDataArr[$k]) ? $countriesDataArr[$k] : 0;            
}

Вы также можете использовать array_merge и array_map as:

$res = array_map(function($v){return 0;}, $countriesArr);
$res = array_merge($countriesArr, $countriesDataArr);

Поскольку второй массив переопределяет первые ключи:

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

array_map преобразует все значения NULL в 0

2 голосов
/ 09 января 2020

Я не знаю точно, как будет сравниваться производительность, но вы могли бы использовать что-то вроде этого, что, я думаю, выглядит чище:

foreach ($all_states as $state => $value) {
  if (isset($country_states[$state])) {
    $all_states[$state] = $country_states[$state];
  } else {
    $all_states[$state] = 0;
  }
}

// If you are running a recent PHP version you could shorten this further
foreach ($all_states as $state => $value) {
  $all_states[$state] = $country_states[$state] ?? 0;
}
1 голос
/ 10 января 2020

Поменяйте значения вашего первого массива на 0, а затем замените значения из второго массива на первый:

<?php

$clothes = 
[
    'hats' => null,
    'shirts' => null,
    'trousers' => null,
    'pants' => null
];

$values = 
[
    'shirts' => 10,
    'hats' => 2
];

var_export(
    array_replace(
        array_fill_keys(array_keys($clothes), 0),
        $values
    )
);

Вывод:

array (
    'hats' => 2,
    'shirts' => 10,
    'trousers' => 0,
    'pants' => 0,
)
1 голос
/ 09 января 2020

Вы можете пройти массив и отобразить другие значения или установить его на 0, если он не существует:

array_walk($all_states, function(&$v, $k) use($country_states) {
                            $v = $country_states[$k] ?? 0;
                        });

Однако я бы просто слил и сохранил значения null или приведение к целому числу:

$all_states = array_map('intval', array_merge($all_states, $country_states));

Вы также можете получить 0 с, например:

$all_states = array_merge(array_flip(array_keys($all_states)), 
                          $country_states);

Или вот так:

$all_states = array_merge(array_fill_keys(array_keys($all_states), 0), 
                          $country_states);
...