views:

58

answers:

6

I'm building a platform. Somewhere in my code, there's an array that looks like this (PHP):

$entries = array('p01','p02','g01','g02','a001','a002')

I need to write a script that filters the array based on the first letter. For example, asking for those with the starting letter "p" would give me

$filtered_entries = array('p01','p02');

Similarly, if I asked for those with starting letter "g" or "a" it would give me those as well. Any idea how to accomplish this?

+6  A: 

There is an array_filter() function in PHP which you can use to accomplish this:

$filtered = array_filter($array, create_function('$a', 'return $a[0] == "' . $letter . '";'));

I'll leave it to you to generalize the function to handle all the letters.

See: http://www.php.net/manual/en/function.array-filter.php

jmz
+1 Exactly my answer, just beat me to it :)
Brad F Jacobs
Technically valid, but creating all the functions for all the different characters may become somewhat cumbersome.
Wrikken
I spoke of generalization to hint that there's a simple way to do it for all the letters Brandon Wang might need that does not consist of copying, pasting and changing one character in the code.
jmz
Better use `var_export` than simple string concatenation.
Gumbo
Ah, the old `create_function`, always smelled a lot like `eval` to me, I seriously had almost forgotten about it since closures. This is a valid working example indeed.
Wrikken
@jmz thanks for your help! I'm a bit confused on how exactly I'm supposed to generalize this code :( Can you help out?
Brandon Wang
This works! I haven't figured out how to generalize but for now it works. Thanks everyone!
Brandon Wang
OK, I can generalize by throwing it into a function.
Brandon Wang
actually, my answer is way better ))
stereofrog
+1  A: 
class FirstCharFilter {
    public $char = 'p';
    function filter(array $array){
        return array_filter($array,array($this,'checkFirstChar'));
    }
    public function checkFirstChar($a){
       return $a[0] == $this->char;
    }
}
$filter = new FirstCharFilter();
$filter->char = 'p';
var_dump($filter->filter($array));
$filter->char = 'g';
var_dump($filter->filter($array));

Or if you only need to loop, extend FilterIterator:

class FirstCharIterator extends FilterIterator {
    public $char = '';
    function accept(){
        $string = $this->current();
        return is_string($string) && $string[0] == $this->char;
    }
}
$iter = new FirstCharIterator(new ArrayIterator($array));
$iter->char = 'p';
foreach($iter as $item) echo $item."\n";
Wrikken
Like the use of the iterator.
Brad F Jacobs
A: 
function filter_array($array, $letter){
$filtered_array=array();
 foreach($array as $key=>$val){
  if($val[0]==$letter){
   $filtered_array[]=$val;
  }
 }
return $filtered_array;
}

use it like this to get all p's

$entries = array('p01','p02','g01','g02','a001','a002')
$filtered=filter_array($entries, 'p');
Christian Smorra
A: 
$entries = array('p01','p02','g01','g02','a001','a002');

$filterVar = null;

function filterFunction($v) {
    global $filterVar;

    if (substr($v,0,1) == $filterVar) {
        return $v;
    }
}

$filterVar = 'a';
$newEntries = array_filter($entries,'filterFunction');


var_dump($newEntries);
Mark Baker
A: 

Here's one way of generating filter functions using a closure.

function filter_factory($letter) {
    return function ($input) use ($letter) {
        return is_string($input) && $input[0] === $letter;
    };
}

$entries   = array('p01','p02','g01','g02','a001','a002');
$p_entries = array_filter($entries, filter_factory('p'));
salathe
A: 
$entries = array('p01','p02','g01','g02','a001','a002');
print_r(
    preg_grep('~^p~', $entries) // or preg_grep("~^$letter~",.....
);

http://php.net/manual/en/function.preg-grep.php

stereofrog