基于多维白名单的多维数组取值

Removing values from multidimensional array based on multidimentional whitelist

我有以下白名单:

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',
        ],
    ]
]

我不知道这是不是"better"。不一样。

代码:(Demo)

$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',
    ),
  ),
)