Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use array_filter() for functional programming in PHP?

Say I have an array of tags

$all_tags = array('A', 'B', 'C');

And I want to create a set of URLs with $_GET variables.
I'd like the links to be:
'A' linking to "index.php?x[]=B&x[]=C"
'B' linking to "index.php?x[]=A&x[]=C"
etc. ($_GET is an array with all elements except for "current" element) (I know there's an easier way to implement this: I'm actually simplifying a more complex situation)

I'd like to use array_filter() to solve this.
Here's my attempt:

function make_get ($tag) { return 'x[]=' . $tag; }
function tag_to_url ($tag_name) {
   global $all_tags;

   $filta = create_function('$x', 'global $all_tags; return ($x != $tag_name);'); 
   return 'index.php?' . implode('&', array_map("make_get", array_filter($all_tags, "filta")));
}
print_r(array_map("", $all_tags));

But it doesn't work. I have a suspicion that maybe it has to do with how maps and filters in PHP actually mutate the data structure themselves, and return a boolean, instead of using a functional style, where they don't mutate and return a new list.

I am also interested in other ways to make this code more succinct.

like image 645
amindfv Avatar asked May 01 '26 16:05

amindfv


1 Answers

Here's an alternative approach:

// The meat of the matter
function get_link($array, $tag) {
    $parts = array_reduce($array, function($result, $item) use($tag)
                          {
                              if($item != $tag) $result[] = 'x[]='.$tag;
                              return $result;
                          });
    return implode('&', $parts);
}

// Test driver

$all_tags = array('A', 'B', 'C');

echo get_link($all_tags, 'A');
echo "\n";
echo get_link($all_tags, 'B');
echo "\n";
echo get_link($all_tags, 'C');
echo "\n";

It's simply one call to array_reduce, and then an implode to pull the results together into a query string.

like image 56
Jon Avatar answered May 03 '26 06:05

Jon