1

I have the following white list:

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

That I want to run agains an array that looks like this:

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

Obviously this are watered down versions of the actual arrays.

My code to do this looks like so:

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;
}

This, however, doesn't seem like it's very clean and makes use of the power of PHP.

Is there a simpler, better, neater way to do this? Something like a recursive array_intersect that works on array keys as well.

This is the outcome that I expect:

[
    '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',
        ],
    ]
]
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Bird87 ZA
  • 2,313
  • 8
  • 36
  • 69

1 Answers1

2

I don't know if this is "better". It is different.

Code: (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);

Or: (with 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);

Or (with array_intersect_key() and modifying by reference):

$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);

Output:

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',
    ),
  ),
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • @Albert looks good to me https://3v4l.org/QiP1J Unfortunately, the `array_intersect_` functions don't allow 2-d array comparisons. Please forgive u_mulder, we regulars get moody sometimes. Just so you know, we have to comment out your `$this` data when we test. – mickmackusa Apr 26 '18 at 13:46
  • This is honestly beautiful. It works perfectly. Thanks @mickmackusa. – Bird87 ZA May 02 '18 at 06:45