46

I have this

$ids = array_map(array($this, 'myarraymap'), $data['student_teacher']);

function myarraymap($item) {
    return $item['user_id'];
}

I will would like to put an other parameter to my function to get something like

function myarraymap($item,$item2) {
    return $item['$item2'];
}

Can someone can help me ? I tried lots of things but nothing work

Mathieu Dumoulin
  • 12,126
  • 7
  • 43
  • 71
user1029834
  • 755
  • 3
  • 9
  • 18
  • What do you want `$item2` to be? A constant value? – knittl Jan 05 '12 at 15:58
  • 1
    I think your call to `array_map` is flawed. Could you provide a proper example? – Felix Kling Jan 05 '12 at 16:01
  • array_map : The number of parameters that the callback function accepts should match the number of arrays passed to the array_map() Trick : You can use a array as param holder e.g. array array_map ( callable $callback, array_to_map,array('param') ) – Ravi Soni May 07 '14 at 09:01
  • Your snippet is the perfect demonstration of how to obscure your code by avoiding native PHP functions. The simpler solution is to not re-invent `array_column()`. https://3v4l.org/ZQXPo See [Is there a function to extract a 'column' from an array in PHP?](https://stackoverflow.com/q/1494953/2943403) – mickmackusa Aug 29 '23 at 02:25

5 Answers5

64

You can use an anonymous function and transmit value of local variable into your myarraymap second argument this way:

function myarraymap($item,$item2) {
    return $item[$item2];
}

$param = 'some_value';

$ids = array_map(
    function($item) use ($param) { return myarraymap($item, $param); },
    $data['student_teacher']
);

Normally it may be enough to just pass value inside anonymous function body:

function($item) { return myarraymap($item, 'some_value'); }

As of PHP 7.4, you can use arrow functions (which are basically short anonymous functions with a briefer syntax) for more succinct code:

$ids = array_map(
    fn($item) => myarraymap($item, $param),
    $data['student_teacher']
);
outis
  • 75,655
  • 22
  • 151
  • 221
Serge S.
  • 4,855
  • 3
  • 42
  • 46
42

PHP's array_map() supports a third parameter which is an array representing the parameters to pass to the callback function. For example trimming the / char from all array elements can be done like so:

$to_trim = array('/some/','/link');
$trimmed = array_map('trim',$to_trim,array_fill(0,count($to_trim),'/'));

Much easier than using custom functions, or other functions like array_walk(), etc.

N.B. As pointed out in the comments below, I was a little hasty and the third param does indeed need to be same length as the second which is accomplished with array_fill().

The above outputs:

array(2) {
  [0]=>
  string(4) "some"
  [1]=>
  string(4) "link"
}
Gleb Kemarsky
  • 10,160
  • 7
  • 43
  • 68
oucil
  • 4,211
  • 2
  • 37
  • 53
  • 4
    It doesn't seem to work the way you described. Test it. The third parameter needs to be an array of elements - each of these elements is passed as an argument together with the matching element from the array being trimmed: `$trimmed = array_map('trim',array('/some/','/link'),array('/', '/'));` – tmt Jul 28 '14 at 10:18
  • @cascaval I had corrected on my own end after noticing the same and forgot to come back to post update. Thanks for the heads up, please see the updated answer, and if useful, please re-vote ;) – oucil Jul 28 '14 at 10:51
  • 1
    What does "N.B." mean? – elbowlobstercowstand Jan 16 '18 at 04:16
  • 1
    @elbowlobstercowstand "nota bene" or take note / note well... It's Latin https://en.m.wikipedia.org/wiki/Nota_bene – oucil Jan 16 '18 at 04:20
  • As useful as this is, I have to say the way the PHP devs have implemented this third param here is a bit absurd since it almost always requires the extremely awkward `array_fill(0,count($to_trim), 'my params')` – But those new buttons though.. May 03 '23 at 17:20
9

Consider using array_walk. It allows you to pass user_data.

anubhava
  • 761,203
  • 64
  • 569
  • 643
5

Apart from creating a mapper object, there isn't much you can do. For example:

class customMapper {
    private $customMap = NULL;
    public function __construct($customMap){
        $this->customMap = $customMap;
    }
    public function map($data){
        return $data[$this->customMap];
    }
}

And then inside your function, instead of creating your own mapper, use the new class:

$ids = array_map(array(new customMapper('param2'), 'map'), $data['student_teacher']);

This will allow you to create a custom mapper that can return any kind of information... And you can complexify your customMapper to accept more fields or configuration easily.

Mathieu Dumoulin
  • 12,126
  • 7
  • 43
  • 71
2

Consider using the third parameter from array_map function to pass additional parameter to callable function. Example:

<?php

function myFunc($item, $param) {
    echo $param . PHP_EOL;
}

$array = ['foo', 'bar'];

array_map('myFunc', $array, ['the foo param', 'the bar param']);

// the foo param
// the bar param

Ref: https://www.php.net/manual/en/function.array-map.php

The docs said about the third param from array_map function: "Supplementary variable list of array arguments to run through the callback function."

Renan Coelho
  • 1,360
  • 2
  • 20
  • 30
  • 1
    Maybe test the code you posted? The output will be 'foo' then 'bar'. If you added a second parameter to `myFunc`, it would be passed `'the param'` only for the first element of `$array`. For subsequent elements it would be passed `null` because “if the arrays are of unequal length, shorter ones will be extended with empty elements to match the length of the longest.” – Jake Oct 21 '20 at 21:29
  • Thank your for pointing out the error. I just updated my answer. – Renan Coelho Oct 23 '20 at 03:23