Удаление значений из многомерного массива на основе многомерного белого списка - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть следующий белый список:

private $conditionalFieldsWhitelist = [
    'Basic Fields' => [
        'contact_name',
        'contact_lastname',
    ],
    'Required Fields' => [
        'some_required_field',
    ]
];

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

$myArray = [
    'Basic Fields' => [
        [
            'field_name' => 'contact_name',
            'field_readable' => $this->language->get('First Name'),
            'field_type' => 'string',
            'field_required' => 'no',
            'field_placeholder' => $this->language->get('Type your first name')
        ], [
            'field_name' => 'contact_lastname',
            'field_readable' => $this->language->get('Last Name'),
            'field_type' => 'string',
            'field_required' => 'no',
            'field_placeholder' => $this->language->get('Type your last name')
        ], [
            'field_name' => 'contact_email',
            'field_readable' => $this->language->get('Email Address'),
            'field_type' => 'string',
            'field_required' => 'yes',
            'field_placeholder' => 'example@domain.com'
        ], [
            'field_name' => 'contact_mobile',
            'field_readable' => $this->language->get('Mobile Number'),
            'field_type' => 'string',
            'field_required' => 'yes',
            'field_placeholder' => '+27881234567'
        ]
    ],
    'Required Fields' => [
        [
            'field_name' => 'some_required_field',
            'field_readable' => $this->language->get('Required Field'),
            'field_type' => 'string',
            'field_required' => 'no',
        ],
    ],
    'This Should Be Removed' => [
        [
            'field_name' => 'not_needed_field',
            'field_readable' => $this->language->get('Required Field'),
            'field_type' => 'string',
            'field_required' => 'no',
        ]
    ]
];

Очевидно, что это разбавленные версии реальных массивов.

Мой код для этого выглядит так:

public function getConditionalFields()
{
    $conditionalFields = $this->formFieldGroupingsViewHelper->getGroupedFields();
    foreach ($conditionalFields as $group => $fields) {
        if (in_array($group, array_keys($this->conditionalFieldsWhitelist)) === false) {
            unset($conditionalFields[$group]);
            continue;
        }
        foreach ($fields as $index => $field) {
            if (in_array($field['field_name'], $this->conditionalFieldsWhitelist[$group]) === false) {
                unset($conditionalFields[$group][$index]);
                continue;
            }
        }
        $conditionalFields[$group] = array_values($conditionalFields[$group]);
    }
    return $conditionalFields;
}

Это, однако, не похоже, что он очень чистый и использует всю мощь PHP.

Есть ли более простой, лучший, аккуратный способ сделать это? Что-то вроде рекурсивного array_intersect, который работает и с ключами массива.

Это результат, который я ожидаю:

[
    'Basic Fields' => [
        [
            'field_name' => 'contact_name',
            'field_readable' => $this->language->get('First Name'),
            'field_type' => 'string',
            'field_required' => 'no',
            'field_placeholder' => $this->language->get('Type your first name')
        ], [
            'field_name' => 'contact_lastname',
            'field_readable' => $this->language->get('Last Name'),
            'field_type' => 'string',
            'field_required' => 'no',
            'field_placeholder' => $this->language->get('Type your last name')
        ]
    ],
    'Required Fields' => [
        [
            'field_name' => 'some_required_field',
            'field_readable' => $this->language->get('Required Field'),
            'field_type' => 'string',
            'field_required' => 'no',
        ],
    ]
]

1 Ответ

0 голосов
/ 26 апреля 2018

Я не знаю, лучше ли это. Это другое.

Код: ( Демо )

$whitegroups = array_keys($conditionalFieldsWhitelist); // only necessary if multiple groups are possible in your project

foreach ($myArray as $group => $field_sets) {
    if (in_array($group, $whitegroups)) {
        $whitesubsets = $conditionalFieldsWhitelist[$group];  // only filter subsets that pass the group check
        $result[$group] = array_filter($field_sets, function($set) use ($whitesubsets) {
            return in_array($set['field_name'],$whitesubsets);  // filter the subsets
        });
    }
}

var_export($result);

Или: (с array_intersect_key())

$myArray = array_intersect_key($myArray, $conditionalFieldsWhitelist);  // filter the groups/keys
foreach ($myArray as $group => $field_sets) {
    $whitesubsets = $conditionalFieldsWhitelist[$group];
    $result[$group] = array_filter($field_sets, function($set) use ($whitesubsets) {
        return in_array($set['field_name'],$whitesubsets);  // filter the subsets
    });
}
var_export($result);

Или (с array_intersect_key() и изменением по ссылке):

$myArray = array_intersect_key($myArray, $conditionalFieldsWhitelist);
foreach ($myArray as $group => &$field_sets) {   // modify by reference
    $whitesubsets = $conditionalFieldsWhitelist[$group];
    $field_sets = array_filter($field_sets, function($set) use ($whitesubsets) {
        return in_array($set['field_name'],$whitesubsets);
    });
}
var_export($myArray);

Выход:

array (
  'Basic Fields' => 
  array (
    0 => 
    array (
      'field_name' => 'contact_name',
      'field_type' => 'string',
      'field_required' => 'no',
    ),
    1 => 
    array (
      'field_name' => 'contact_lastname',
      'field_type' => 'string',
      'field_required' => 'no',
    ),
  ),
)
...