Return a single Element from an Associative Array from a Function

952 Views Asked by At

Lets assume we have two PHP-Arrays:

 $some_array = array('a','b','c','d','e','f');
 $another_array = array(101,102,103,104,105,106);

In PHP, there are already some Array-Functions that allow the construction of an Associative Array (AKA hash), e,g,;

 $hash = array_combine(
           $some_array,
           $another_array
         );

And here it comes. What should I do if I want to create a hash in a more functional style, if I want to compute key and value on the fly and build the hash through a map-operation, like (not working):

 # wishful thinking
 $hash = array_map(
            function($a, $b){ return ($a => $b); },
            $some_array,
            $another_array
         );

The problem here seems to be the expectation, the line

            ...
            function($a, $b){ return ($a => $b); }
            ...

would indeed return an key value/pair of a hash - which it doesn't.

Q: How can I return a key/value pair from a function - which can be used to build up an associative array?


Addendum

To make clear what I really was looking for, I'll provide a perl example of hash generation:

 ...
 # we have one array of characters (on which our hash generation is based)

 my @array = qw{ a b c d e f };

 # now *generate* a hash with array contents as keys and 
 # ascii numbers as values in a *single operation *
 # (in Perl, the $_ variable represents the actual array element)

 my %hash = map +($_ => ord $_), @array;
 ...

Result (%hash):

 a => 97
 b => 98
 c => 99
 d => 100   
 e => 101
 f => 102

From the responses, I'd now think this is impossible in PHP. Thanks to all respondends.


3

There are 3 best solutions below

2
On BEST ANSWER

EDIT: It's not entirely clear whether you're having a problem merely with returning multiple variables from a function, or whether you're having problems storing a function in an array. Your post gives the impression that storing the function in the array works, so I'll tackle the return-multiple-variables problem.

There is no way to return a single instance of a key/value pair in PHP. You have to have them in an array... but remember that in PHP, an array and hashmap are exactly the same thing. It's weird (and controversial), but that means it's perfectly legitimate to return an array/hashmap with the multiple values you wish to return.

There are only two sane ways that I know (from 10+ years of PHP experience) to get more than one variable out of a function. One is the good'ol fashion way of making the input variable changeable.

function vacuumPackSandwitch(&$a, &$b) {
    $a = 505;
    $b = 707;
}

This will change both $a and $b as opposed to changing copies of them like usual. For example:

$a = 1;
$b = 2;
vacuumPackSandwitch($a, $b);
print $a.' '.$b;

This will return "505 707", not "1 2" like normally. You might have to do:

vacuumPackSandwitch(&$a, &$b);

But if that's the case, the PHP compiler will duly let you know.

The other way is to return an array, which I suppose is the clearer and preferred way.

function ($a, $b) {
    return array($a, $b);
}

You can grab both variables at the same time by doing:

list($c, $d) = vacuumPackSandwitch($a, $b);

Hope it helps!

1
On

In PHP arrays can be associative too! An int-indexed array is just an associative array with 0 => element0 and so on. Thus, you can accomplish what you are looking for like this:

$somearray = array('name' => 'test', 'pass' => '***', 'group' => 'admin');

function myfunc($a, $b) { return array($a => $b); }

if($somearray['name'] == 'test') { echo 'it works!'; }

// Let's add more data with the function now
$somearray += myfunc('location', 'internet');

//Test the result
if($somearray['location'] == 'internet') { echo 'it works again!'; }

It is really very simple. Hope this helps.

0
On

I know that this is an old question, but google still likes it for a search I recently made, so I'll post my findings. There are two ways to do this that come close to what you're attempting, both relying on the same general idea.

Idea 1:

Instead of returning a key => value pair, we return an array with only one element, 'key => value', for each sequential element of the original arrays. Then, we reduce these arrays, merging at every step.

$array = array_map(
    function($a, $b){
        return array($a => $b);
    },
    $arr1,
    $arr2
);
$array = array_reduce(
    $array,
    function($carry, $element){
        $carry = array_merge($carry, $element);
        return $carry;
    },
    array()
);

OR

Idea 2:

Similar to idea one, but we do the key => value assignment in array_reduce. We pass NULL to array_map, which creates an array of arrays (http://php.net/manual/en/function.array-map.php)

$array = array_map(NULL, $a, $b);
$array = array_reduce(
    $array,
    function($carry, $element){
        $carry[$element[0]] = $element[1];
        return $carry;
    },
    array()
);

Personally, I find Idea 2 to be a lot more elegant than Idea 1, though it requires knowing that passing NULL as the function to array_map creates an array of arrays and is therefore somewhat un-intuitive. I just think of it as a precursor to array_reduce, where all the business happens.

Idea 3:

$carry = array();
$uselessArray = array_map(
    function($a, $b) use ($carry){
        $carry[$a] = $b;
    },
    $a,
    $b
);

Idea 3 is an alternative to Idea 2, but I think it's hackier than Idea 2. We have to use 'use' to jump out of the function's scope, which is pretty ugly and probably contrary to the functional style OP was seeking.

Lets just streamline Idea 2 a little and see how that looks:

Idea 2(b):

$array = array_reduce(
    array_map(NULL, $a, $b),
    function($carry, $element){
        $carry[$element[0]] = $element[1];
        return $carry;
    },
    array()
);

Yeah, that's nice.