1

I am very new in PHP & would like to revamp below multidiemensional array. These array i am getting from JSON submit of a FORM with lots of 'name' & 'value' but i need to spread out few set of values. Here i only given a example that is similar of my work.

$formValues = array(
    array(
        'name' => 'name-agent-1',
        'value' => 'austin'
    ),
    array(
        'name' => 'company-agent-1',
        'value' => 'Samsung'
    ),
    array(
        'name' => 'phone-agent-1',
        'value' => '889410'
    ),
    array(
        'name' => 'mail-agent-1',
        'value' => 'abc@mail.com'
    ),
    array(
        'name' => 'name-agent-2',
        'value' => 'Justin'
    ),
    array(
        'name' => 'company-agent-2',
        'value' => 'Nokia'
    ),
    array(
        'name' => 'phone-agent-2',
        'value' => '332100'
    ),
    array(
        'name' => 'mail-agent-2',
        'value' => 'xyz@mail.com'
    ),
    array(
        'name' => 'name-agent-3',
        'value' => 'stefen'
    ),
    array(
        'name' => 'company-agent-3',
        'value' => 'Motorolla'
    ),
    array(
        'name' => 'phone-agent-3',
        'value' => '8744520'
    ),
    array(
        'name' => 'mail-agent-3',
        'value' => 'tyu@mail.com'
    )
);

From the above example of Multi-dimensional array i would like to re-build on below format:

Array
  (
   [1] => Array
       (
        [name-agent-1] => austin
        [company-agent-1] => Samsung
        [phone-agent-1] => 889410
        [mail-agent-1] => abc@mail.com
    )
  [2] => Array
    (
        [name-agent-2] => Justin
        [company-agent-2] => Nokia
        [phone-agent-2] => 332100
        [mail-agent-2] => xyz@mail.com
    )
  [3] => Array
    (
        [name-agent-3] => stefen
        [company-agent-3] => Motorolla
        [phone-agent-3] => 8744520
        [mail-agent-3] => tyu@mail.com
    )
)

I need your the shortest & easiest way to make this happen. Please help and appreciated the suggestion that makes sense. Thanks in advance.

raina77ow
  • 91,589
  • 12
  • 180
  • 210

2 Answers2

0

One possible approach:

$mapped = array();
$group = 0; // assuming you indeed have to start indexing with 1, as in the question
foreach ($formValues as $i => $arr) {
  if ($i % 4 === 0) {
    $group++;
  }
  $mapped[$group][ $arr['name'] ] = $arr['value'];
}

Demo. There's nothing really complicated here: with foreach, you iterate over the source array, filling out $mapped one with keys and values, taken from name and value correspondingly. And you have another property - $no - for grouping these elements by 4.


In the code above I've assumed the source array always has the same structure. If it's not, you'll have to do additional checks within the loop, extracting the group number off the name:

$mapped = array();
foreach ($formValues as $arr) {
  $name = $arr['name'];
  if (preg_match('/(?<=-)\d+$/', $name, $m)) {
    $mapped[ $m[0] ][$name] = $arr['value'];
  }
}
raina77ow
  • 91,589
  • 12
  • 180
  • 210
  • That's awesome :) & it worked for me. I just had a question here: what is the difference between `if ($i % 4 === 0)` && `if ($i % 4 == 0)` ?? – Mehedi Hasan Dec 13 '14 at 14:35
  • It's a strict comparison operator. Check [this question](http://stackoverflow.com/questions/80646/how-do-the-php-equality-double-equals-and-identity-triple-equals-comp) for details. – raina77ow Dec 13 '14 at 14:46
0

Try this:

$out = array_reduce(
    $formValues,
    function (array $carry, array $item) {
        $name = $item['name'];
        $id   = end(explode('-', $name));
        if (! isset($carry[$id])) {
            $carry[$id] = array();
        }
        $carry[$id][$name] = $item['value'];
        return $carry;
    },
    array()
);

print_r($out);

The code groups the input values by the last component of 'name', using '-' as separator. The input values can be in any order, some of them may be missing and there is no request to have all the values for all the groups. For example, if mail-agent-2 is missing the code still works and groups the rest of the values correctly by their IDs.

axiac
  • 56,918
  • 8
  • 77
  • 110