11

I have an array such as ['id' => 1, 'name' => 'Fred'].

I want to call array_map on this array and also use the key inside the function. However, when I make a return, my keys will become int.

Simple example :

$arr = array('id' => 1, 'name' => 'Fred');
$result = array_map(
    function ($value, $key) {
        return $value;
     },
     $arr,
     array_keys($arr)
);
var_dump($result);

Basically, I want $result to be identical to $arr in this case, but it turns my string keys into ints.

K-Gun
  • 10,689
  • 2
  • 52
  • 56
user2816456
  • 529
  • 2
  • 5
  • 15
  • 1
    You need to show what result you want. This works as it should. – AbraCadaver Aug 26 '14 at 19:15
  • 3
    From the documentation "If the array argument contains string keys then the returned array will contain string keys if and only if exactly one array is passed. _If more than one argument is passed then the returned array always has integer keys_." (emphasis mine) – Patrick Q Aug 26 '14 at 19:16
  • `array_map()` is an inappropriate tool for this job. Show us what you actually want to do with this daya. – mickmackusa Mar 08 '20 at 10:22

5 Answers5

22

For your requirement of "I want to call array_map" and "$result to be identical to $arr", try:

$result = array_combine(
     array_keys($arr), 
     array_map(function($v){ return $v; }, $arr)
);

Gives:

   [
     "id" => 1
     "name" => "Fred"
   ]

But heh, if all you want is identical arrays, then nothing beats this code:

$result = $arr;
Jannie Theunissen
  • 25,269
  • 20
  • 97
  • 121
  • This is not a good generic solution because the transformation function does not have access to the current key. – Walf Mar 24 '22 at 07:25
14

The closest you will get using array_map() is this:

<?php
$arr = array('id'=>1,'name'=>'Jon');

$callback = function ($key, $value) {
    return array($key => $value);
  };

$arr = array_map( $callback, array_keys($arr), $arr);
var_dump($arr);
?>

Gives:

   [
     [
       "id" => 1
     ],
     [
       "name" => "Jon"
     ]
   ]

You will be better creating your own function with a foreach inside.

Jannie Theunissen
  • 25,269
  • 20
  • 97
  • 121
Marcos
  • 972
  • 11
  • 20
2

What you need is array_walk. Try this code:

$arr = array('id' => 1, 'name' => 'Fred');
array_walk(
    $arr,
    function (&$value, $key) {
        // do stuff
     }
);
print_r($arr);

Unfortunally it works not when you try to change the keys. But you can change the values when you pass them by refference.

If you have to change the keys too, check Question to array_walk-change-keys and the first answer:

Radon8472
  • 3,493
  • 1
  • 27
  • 38
2

Based on @Jannie Theunissen answer the correct way of getting an array_map working with key for comparing and assigning values based on second array for example is:

$result = array_combine(
 array_keys($arr), 
 array_map(function($v, $key){ return $v; }, $arr, array_keys($arr))
);

Or for optimized alternative:

$keys = array_keys($arr);
$result = array_combine(
 $keys, 
 array_map(function($v, $key){ return $v; }, $arr, $keys)
);

And with a comparison array value:

$compareArray = [/*same structure as $arr but with specific values*/];
$keys = array_keys($arr);
$result = array_combine(
 $keys, 
 array_map(function($v, $key) use ($compareArray) { 
              // recursive can be achieved here passing $v and $compareArray[$key]
              return $compareArray[$key]; 
           }, $arr, $keys)
);
סטנלי גרונן
  • 2,849
  • 23
  • 46
  • 65
user3550312
  • 108
  • 1
  • 6
0

The idea is quite simple. You need to use keys inside your array_map() function.

For this purpose we add two arrays: the first one array_keys($array) we pass the keys of our major array and the second one $array is the needed array.

array_map(function($key, $value) {

       // use your key here ...
       return $processed_value;

    }, array_keys($array), $array)

From now on: you can use the $key as a value from first param and $value as a second param.

muinh
  • 385
  • 5
  • 13