16

I am using array_filter to do something like this:

function endswithy($value) {
    return (substr($value, -1) == 'y');
}

$people = array("Johnny", "Timmy", "Bobby", "Sam", "Tammy", "Danny", "Joe");
$withy = array_filter($people, "endswithy");
var_dump($withy);

BUT with the more option in filter for example

$people = array(
             "Johnny"=>array("year"=>1989, "job"=>"prof"),
             "Timmy"=>array("year"=>1989,  "job"=>"std"),
             "Bobby"=>array("year"=>1988),
             "Sam"=>array("year"=>1983),
             "Tammy"=>array("year"=>1985),
             "Danny"=>array("year"=>1983),
             "Joe"=>array("year"=>1989,"job"=>"prof"));

OR

$people = array(
             array("name"=>"Johnny","year"=>1989, "job"=>"prof"),
             array("name"=>"Timmy","year"=>1989,  "job"=>"std"),
             array("name"=>"Bobby""year"=>1988),
             array("name"=>"Sam","year"=>1983),
             array("name"=>"Tammy","year"=>1985),
             array("name"="Danny","year"=>1983),
             array("name"="Joe","year"=>1989,"job"=>"prof"));

How Can I got the only this people (endwith y and year=1989 and job=prof) ,Can I use array_filter? or any build-in function to do this?

$people = array(
                 "Johnny"=>array("year"=>1989, "job"=>"prof")
  );

OR

$people = array(
                 array("name="Johnny","year"=>1989, "job"=>"prof")
  );
2
  • Can you use name as a value of inner array rather than key of outer array? I.e., $people = array(array('name' => 'Johnny', 'year' => 1989, 'job' => 'prof'), ...) Commented Jun 1, 2011 at 10:15
  • If you can do it, then there's no problem with using array_filter(). You'll get array as argument of callback function (endswithy()), so you can check both name and year. If you need this only once, you might also use foreach loop for removing items that are not needed. I've given examples with both array_filter() and foreach in my answer below. Commented Jun 1, 2011 at 10:24

2 Answers 2

25

PHP 5.6 introduces the optional flag ARRAY_FILTER_USE_KEY that will allow this:

function endswithy($name) {
    return (substr($name, -1) == 'y');
}

$people = array(
     "Johnny"=>array("year"=>1989, "job"=>"prof"),
     "Timmy"=>array("year"=>1989,  "job"=>"std"),
     "Bobby"=>array("year"=>1988),
     "Sam"=>array("year"=>1983),
     "Tammy"=>array("year"=>1985),
     "Danny"=>array("year"=>1983),
     "Joe"=>array("year"=>1989,"job"=>"prof")
);

$peopleEndingInY = array_filter($people, 'endswithy', ARRAY_FILTER_USE_KEY);

// Outputs: 5
var_dump(count($peopleEndingInY));

If you need to maintain and key and the value, another flag ARRAY_FILTER_USE_BOTH will do that as seen in this example:

$ar = array(
    'key1' => 'value1',
    'key2' => 'value2'
);

//Note that this doens't actually filter anything since it doesn't return a bool.
$output = array_filter($ar, function($value, $key){
    echo sprintf("%s => %s\n", $key, $value);
}, ARRAY_FILTER_USE_BOTH);
Sign up to request clarification or add additional context in comments.

1 Comment

a great answer that doesn't require you to change your data structure.
10

Either use foreach with your current array's structure:

$people = array(
    "Johnny" => array("year" => 1989, "job" => "prof"),
    "Timmy"  => array("year" => 1989, "job" => "std"),
    "Bobby"  => array("year" => 1988),
    "Sam"    => array("year" => 1983),
    "Tammy"  => array("year" => 1985),
    "Danny"  => array("year" => 1983),
    "Joe"    => array("year" => 1989, "job" => "prof"),
);

foreach ( $people as $name => $info ) {
    if ( substr($name, -1) !== 'y' || $info['year'] != 1989 ) {
        unset($people[$name]);
    }
}

print_r($people);

// output:
Array
(
    [Johnny] => Array
        (
            [year] => 1989
            [job] => prof
        )
    [Timmy] => Array
        (
            [year] => 1989
            [job] => std
        )
)

Or convert your array so that name is value of inner array:

$people = array(
    array('name' => 'Johnny', 'year' => 1989, 'job' => 'prof'),
    array('name' => 'Timmy' , 'year' => 1989, 'job' => 'std'),
    array('name' => 'Bobby' , 'year' => 1988),
    array('name' => 'Sam'   , 'year' => 1983),
    array('name' => 'Tammy' , 'year' => 1985),
    array('name' => 'Danny' , 'year' => 1983),
    array('name' => 'Joe'   , 'year' => 1989, 'job' => 'prof'),
);

function filter($item) {
    return substr($item['name'], -1) === 'y' && $item['year'] == 1989;
}

$filteredPeople = array_filter($people, 'filter');

print_r($filteredPeople);

// output:
Array
(
    [0] => Array
        (
            [name] => Johnny
            [year] => 1989
            [job] => prof
        )
    [1] => Array
        (
            [name] => Timmy
            [year] => 1989
            [job] => std
        )
)

4 Comments

in the second example why we need to convert $people array?is it the limitation of array_filter?
No, it is not limitation of array_filter(). If you do not need $people in its original form after filtering, you can safely assign result to $people, i.e., $people = array_filter($people, 'filter');.
sorry binaryLV .your code it works perfectly ,but I did not understand,.what you explain in your comments here.can you give more example on this.thank so much.
What did you mean with your question in the first comment (about converting $people)? Was that about $filteredPeople = array_filter($people, 'filter'); line? If yes, you can safely write $people = array_filter($people, 'filter');.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.