0

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?

Brandon Wang
  • 3,701
  • 7
  • 31
  • 36

7 Answers7

8

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
  • 5,399
  • 27
  • 29
  • Technically valid, but creating all the functions for all the different characters may become somewhat cumbersome. – Wrikken Jul 29 '10 at 20:11
  • 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 Jul 29 '10 at 20:15
  • Better use `var_export` than simple string concatenation. – Gumbo Jul 29 '10 at 20:32
  • 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 Jul 29 '10 at 20:52
  • @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 Jul 29 '10 at 23:32
  • This works! I haven't figured out how to generalize but for now it works. Thanks everyone! – Brandon Wang Jul 29 '10 at 23:50
  • OK, I can generalize by throwing it into a function. – Brandon Wang Jul 29 '10 at 23:53
  • actually, my answer is way better )) – user187291 Jul 31 '10 at 18:13
1
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
  • 69,272
  • 8
  • 97
  • 136
1
$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

user187291
  • 53,363
  • 19
  • 95
  • 127
0
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
  • 1,756
  • 11
  • 13
0
$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
  • 209,507
  • 32
  • 346
  • 385
0

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
  • 51,324
  • 12
  • 104
  • 132
0

This type of solution is much more intuitive and dynamic. In this example, there are several types of solutions:

  • Search in the first letters
  • Sensitive to capital letters
  • is_array() so if it tends to avoid several errors

<?php

/*
 * Search within an asociative array
 * Examples:
 * $array = array('1_p01','1_P02','2_g01','2_g02','3_a001','3_a002');
 * find_in_array($array,'2');
 * return:  array( 2 => '2_g01',3 => '2_g02')
 *
 * find_in_array($array,'2',false);
 * return:  array( 1 => '1_P02')
 *
 * find_in_array($array,'P0',false,false);
 * return: array( 0 => '1_p01',1 => '1_P02')
 *
 */

function find_in_array($array, $find='', $FirstChar=true, $CaseInsensitive=true){
    if ( is_array($array) ){
        return preg_grep("/".($FirstChar ? '^':'')."{$find}/".($CaseInsensitive ? '':'i'), $array);
    }
}

$array = array('1_p01','1_P02','2_g01','2_g02','3_a001','3_a002');

$a = find_in_array($array,'2');
var_export($a);
/*
Return: 
array (
  2 => '2_g01',
  3 => '2_g02'
)
*/

$a = find_in_array($array,'P0',false);
var_export($a);
/*
Return: 
array (
  1 => '1_P02'
)
*/

$a = find_in_array($array,'P0',false,false);
var_export($a);
/*
Return: 
array (
  0 => '1_p01',
  1 => '1_P02'
)
*/
Clary
  • 544
  • 1
  • 7
  • 8