Access first level keys with array_map() without calling `array_keys()`
Not with array_map, as it doesn't handle keys.
array_walk does:
$test_array = array("first_key" => "first_value",
"second_key" => "second_value");
array_walk($test_array, function(&$a, $b) { $a = "$b loves $a"; });
var_dump($test_array);
// array(2) {
// ["first_key"]=>
// string(27) "first_key loves first_value"
// ["second_key"]=>
// string(29) "second_key loves second_value"
// }
It does change the array given as parameter however, so it's not exactly functional programming (as you have the question tagged like that). Also, as pointed out in the comment, this will only change the values of the array, so the keys won't be what you specified in the question.
You could write a function that fixes the points above yourself if you wanted to, like this:
function mymapper($arrayparam, $valuecallback) {
$resultarr = array();
foreach ($arrayparam as $key => $value) {
$resultarr[] = $valuecallback($key, $value);
}
return $resultarr;
}
$test_array = array("first_key" => "first_value",
"second_key" => "second_value");
$new_array = mymapper($test_array, function($a, $b) { return "$a loves $b"; });
var_dump($new_array);
// array(2) {
// [0]=>
// string(27) "first_key loves first_value"
// [1]=>
// string(29) "second_key loves second_value"
// }
array_map with access to keys
I'm afraid array_walk()
IS the way to do this.
If you don't like array_walk()
and insist on doing it with array_map()
, well, it's possible. It involves using also array_keys()
, array_values()
and array_combine()
, it is long and ugly but doable:
$myNewArray = array_combine(
array_keys($myArray),
array_map(
function($key, $value) {
if ($key == 'key1') {
$value['newkey'] = 'only for key1';
}
return $value;
},
array_keys($myArray),
array_values($myArray) // can omit array_values() and use $myArray
)
);
You can also do it using array_reduce()
but it's the same mess:
$myNewArray = array_reduce(
array_keys($myArray),
function (array $carry, $key) use ($myArray) {
$value = $myArray[$key];
if ($key == 'key1') {
$value['newkey'] = 'only for key1';
}
$carry[$key] = $value;
return $carry;
},
array()
);
I hope you have a condition more complex than $key == 'key1'
because only for this it is not worth it writing complex traversal. Isn't it easier to just access the right element and modify it?
$myArray['key1']['newkey'] = 'only for key1';
How to modify index keys using array_map() in PHP
What about the following:
$desired_output = array();
array_walk(
$data,
function(&$val, $key) use (&$desired_output)
{
$len = strlen('posted_');
if (substr($key, 0, $len) == "posted_") {
$key = substr($key, $len);
}
$desired_output[$key] = $val;
}
);
print_r($desired_output);
Changes:
- Using
array_walk
instead ofarray_map
since _map cannot handle keys - Creating an empty array to build the result in
- Using that array in the scope of the lambda function
- Replacing the "posted_" only if it exists in the key
Output:
$ php -f ~/tmp/so2.php
Array
(
[name] => John Doe
[age] => 30
)
Array mapping in PHP with keys
Just use array_reduce
:
$obj1 = new stdClass;
$obj1 -> id = 12;
$obj1 -> name = 'Lorem';
$obj1 -> email = 'lorem@example.org';
$obj2 = new stdClass;
$obj2 -> id = 34;
$obj2 -> name = 'Ipsum';
$obj2 -> email = 'ipsum@example.org';
$reduced = array_reduce(
// input array
array($obj1, $obj2),
// fold function
function(&$result, $item){
// at each step, push name into $item->id position
$result[$item->id] = $item->name;
return $result;
},
// initial fold container [optional]
array()
);
It's a one-liner out of comments ^^
Related Topics
Hunting Cheaters in a Voting Competition
Update Command-Line Output, I.E. for Progress
How to Convert All Images to Jpg Format in PHP
How to Get Data in Function Extend Controller
Call to Undefined Function Odbc_Connect() Message While Connecting Sap Hana Database
Pushnotification Server Side Implementation
Image - Upload Not Responding, No Access to $_Files
Mysqli Prepared Statement Column with Variable
Better Way to Check Variable for Null or Empty String
Convert Clickable Anchor Tags to Plain Text in HTML Document
How to Output in Cli During Execution of PHP Unit Tests
How to Debug Why Simplest MySQL Query Returns False
Algorithm to Get the Excel-Like Column Name of a Number