0
\$\begingroup\$

Very difficult to explain in a sentence sorry so here is example.

I have this array:

$setParams = [
    'repeat_delay' => [23, 1],
    'repeat_type' => ['Hour', 'Day'],
];

that I want to turn into this

$wanted = [
    [
        'repeat_delay' => 23,
        'repeat_type' => 'Hour'
    ],
    [
        'repeat_delay' => 1,
        'repeat_type' => 'Day'
    ]
];

I have it working but wanting to know if there is a cleaner way, or even another way.

$newArray = [];
$setKeys = array_keys($setParams);
$setValues = array_values($setParams);

$isSetValueArray = array_filter($setValues,
    static function ($setValue) {
        return is_array($setValue);
    });

if (!empty($isSetValueArray)) {
    foreach ($setKeys as $keyCount => $key) {
        foreach ($setValues as $valueCount => $value) {
            if (is_array($value)) {
                foreach ($value as $k => $v) {
                    if ($keyCount === $valueCount) {
                        $newArray[$k][$key] = $v;
                    }
                }
            }
        }
    }
}

Some more information to help others. I am sorry I didn't provide sooner as I know context is everything.

Here is a link to my snippet with more info and complete example.

https://gitlab.mrwilde.solutions/-/snippets/18

\$\endgroup\$
5
  • \$\begingroup\$ Please add more information about your code in the body, its very difficult to understand " I have this" \$\endgroup\$ – Parekh Nov 7 '20 at 9:40
  • \$\begingroup\$ Is that better? Is there a specific question you have I may be able to fill in the blanks better. \$\endgroup\$ – Robert Wilde Nov 7 '20 at 10:13
  • 1
    \$\begingroup\$ What is the purpose of this code? We need to know more about the code before we can provide a good review. \$\endgroup\$ – pacmaninbw Nov 7 '20 at 14:49
  • \$\begingroup\$ This is called "array transposing" and there will be plenty of answers on Stack Overflow to demonstrate the available techniques. Hello Mr. Wilde, see you at the next PHP Meetup. It looks like you are also doing some filtering. Perhaps your sample data is not representing the fringe cases that your code can accommodate. Will your input data always be a complete "matrix", or might it have gaps in values? \$\endgroup\$ – mickmackusa Nov 9 '20 at 11:44
1
\$\begingroup\$

Assuming you have the same number of items for each key, here are two alternative approaches:

Foreach:

<?php
$setParams = [
    'repeat_delay' => [23, 1],
    'repeat_type'  => ['Hour', 'Day'],
];

$i = 0;
foreach($setParams['repeat_delay'] as $k => $v) {
    $result[$i]['repeat_delay'] = $v;
    $result[$i]['repeat_type']  = $setParams['repeat_type'][$k];
    $i++;
}

Array map:

$result = array_map(null, ...array_values($setParams));
$keys   = array_keys($setParams);
$result = array_map(function($v) use ($keys) { return array_combine($keys, $v);}, $result);

Both result in $result holding the following:

array (
  0 => 
  array (
    'repeat_delay' => 23,
    'repeat_type' => 'Hour',
  ),
  1 => 
  array (
    'repeat_delay' => 1,
    'repeat_type' => 'Day',
  ),
)

You could rewrite the last array_map with the array_combine to:

$result = array_map(fn($v) => array_combine($keys, $v), $result);

Using a short arrow function for brevity.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.