user2816456
user2816456

Reputation: 597

How can I use array_map with keys and values, but return an array with the same indexes (not int)?

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 indexed.

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 without reindexing my array.

Upvotes: 17

Views: 69659

Answers (6)

Radon8472
Radon8472

Reputation: 4991

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

Unfortunately, it cannot change the keys but you can change the values if your callback uses them by reference.

If you have to change the keys too, check my other answer regarding reindexing with array_walk().

Upvotes: 6

Walf
Walf

Reputation: 9348

I don't think I came up with this, but I don't remember where I got it, either.

This function is generic, has the same variadic signature as array_map(), but preserves the keys of the first array passed, and the callback gets the current key as the first arg and the value(s) as the subsequent arg(s), like function ($k, $v, $v2, ..., $vn) {, (whereas array_map() only gets the array values).

function array_map_assoc(callable $callback, array $array, array ...$arrays) {
    $keys = array_keys($array);
    array_unshift($arrays, $keys, $array);
    return array_combine($keys, array_map($callback, ...$arrays));
}

Example: https://3v4l.org/9XQF9

Other examples here have function ($v, $k) { as the callback signature but they're limited to one input array, and it doesn't make sense to have the key in the middle of the values when accepting multiple input arrays.

Upvotes: 0

Jannie Theunissen
Jannie Theunissen

Reputation: 30114

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;

Upvotes: 30

muinh
muinh

Reputation: 615

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.

Upvotes: 0

user3550312
user3550312

Reputation: 128

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

Upvotes: 3

Marcos
Marcos

Reputation: 1378

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.

Upvotes: 13

Related Questions