0

I have encountered an array of serialized values like below:

Array
(
    [primary] => Array
        (
            [key_type_0_key_name] => a:1:{i:0;s:5:"27232";}
            [key_type_1_key_name] => a:1:{i:0;s:5:"27231";}
            [key_type_2_key_name] => a:1:{i:0;s:5:"27147";}
            [key_type_3_key_name] => a:1:{i:0;s:5:"27157";}
        )

    [additional] => Array
        (
            [key_type_0_key_othername] => a:1:{i:0;s:5:"27169";}
            [key_type_1_key_othername] => a:1:{i:0;s:5:"27160";}
            [key_type_2_key_othername] => a:1:{i:0;s:5:"27103";}
            [key_type_3_key_othername] => a:1:{i:0;s:5:"27149";}
        )
)

Now I need to apply two functions namely, unserialize and array_shift in specified order to extract the scalar values like 27169 and store in another array, how can I do that in one pass of array_map or I have to run array_map two times compulsorily ?

Also one problem is with recursion, only array_walk_recursive handles recursion properly, but in my case if I try below code, I am getting the given error:

return array_walk_recursive($array, function ( &$value ) {
        $value = array_shift( unserialize( $value ) );
    });

Error:

 Strict Standards: Only variables should be passed by reference in /path/to/file.php on line 367

Expected Result:

Array
(
    [primary] => Array
        (
            27232
            27231
            27147
            27157
        )

    [additional] => Array
        (
            27169
            27160
            27103
            27149
        )
)
VST
  • 131
  • 1
  • 10
  • who told you can do that in one pass in first place and why it is that really makes a difference? – Marcin Orlowski Sep 04 '17 at 09:26
  • It was just a thought and try, as I have a large array(lot larger than the one mentioned in question) also read my updated question, if it may help – VST Sep 04 '17 at 09:28
  • If you store the unserialized value in a variable and then do the array_shift it will fix the should be passed by reference error. – Progrock Sep 04 '17 at 09:30
  • As you see, sub-array keys if can be maintained be well and good, but they aren't as important but the values are... – VST Sep 04 '17 at 09:48

2 Answers2

2

With no calls to array_map.

<?php

$data = [
    'primary' =>
    [
        'a:1:{i:0;s:5:"27232";}',
        'a:1:{i:0;s:5:"27231";}',
        'a:1:{i:0;s:5:"27147";}',
        'a:1:{i:0;s:5:"27157";}'
    ],
    'additional' =>
    [
        'a:1:{i:0;s:5:"27169";}',
        'a:1:{i:0;s:5:"27160";}',
        'a:1:{i:0;s:5:"27103";}',
        'a:1:{i:0;s:5:"27149";}'
    ]
];



$numbers = [];
foreach($data as $key=>$value) {
    foreach($value as $k=>$v) {
        $unserialized = unserialize($v);
        $numbers[$key][] = (int) array_shift($unserialized);
    }
}

var_dump($numbers);

Output:

array (size=2)
  'primary' => 
    array (size=4)
      0 => int 27232
      1 => int 27231
      2 => int 27147
      3 => int 27157
  'additional' => 
    array (size=4)
      0 => int 27169
      1 => int 27160
      2 => int 27103
      3 => int 27149

Here a mutating array_walk example with three array_map calls. Far uglier and harder to read in my eyes, but each their own:

array_walk($data, function(&$v) {
        $v = array_map('intval', array_map('array_shift', array_map('unserialize', $v)));
    }
);
var_dump($data);

Output:

    array (size=2)
      'primary' => 
        array (size=4)
          0 => int 27232
          1 => int 27231
          2 => int 27147
          3 => int 27157
      'additional' => 
        array (size=4)
          0 => int 27169
          1 => int 27160
          2 => int 27103
          3 => int 27149
Progrock
  • 7,373
  • 1
  • 19
  • 25
  • Thanks for a `foreach` based answer, but can this be done with array_map or `array_walk_recursive`, I have used those functions for most of my array operations and I don't want to break the trend frankly. – VST Sep 04 '17 at 09:36
  • @VST, array_walk_recursive works on leaf nodes, so more difficult to associate keys. I've added an array_walk example. – Progrock Sep 04 '17 at 10:13
  • It's ok, as I said, the sub-array keys are not important, thanks for `array_walk` example. – VST Sep 04 '17 at 10:17
1

Allow me to answer the question that was asked. Yes, yes you can... and you nearly had it!

You only needed to change the way that you were accessing the value. Replace the array_shift() call with [0] -- this eliminates the Strict Standards error.

Code: (Demo)

$array=[
    'primary' =>
    [
        'a:1:{i:0;s:5:"27232";}',
        'a:1:{i:0;s:5:"27231";}',
        'a:1:{i:0;s:5:"27147";}',
        'a:1:{i:0;s:5:"27157";}'
    ],
    'additional' =>
    [
        'a:1:{i:0;s:5:"27169";}',
        'a:1:{i:0;s:5:"27160";}',
        'a:1:{i:0;s:5:"27103";}',
        'a:1:{i:0;s:5:"27149";}'
    ]
];
array_walk_recursive($array,function(&$v){$v=unserialize($v)[0];});
var_export($array);

Output:

array (
  'primary' => 
  array (
    0 => '27232',
    1 => '27231',
    2 => '27147',
    3 => '27157',
  ),
  'additional' => 
  array (
    0 => '27169',
    1 => '27160',
    2 => '27103',
    3 => '27149',
  ),
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136