1

Title explains it all, I know how to do this the long way but I have always wondered if there was a shorter way to do so.

Lets say,

$mutli = array(
    array('name' => 'john', 'adult' => 'true'  ),
    array('name' => 'eric', 'adult' => 'true'  ),
    array('name' => 'ryan', 'adult' => 'false' )
);

Is there a better way to select all lower arrays where adult == true?

$list = array();
foreach( $multi as $sub ){
    foreach( $sub as $key => $value ){
        if( $key == "adult" && $value == "true" )
            array_push( $list, $sub );
    }
}

Not urgent, but I was always curious.

perhaps,

while( $key => $value as each($mutli) )

or something :p

MysteryDev
  • 610
  • 2
  • 12
  • 31
  • Please accept an answer or add your own answer and accept it. Doing that will prevent appearing this question as unanswered. @MysteryDev – Charlotte Dunois Feb 01 '16 at 20:01

3 Answers3

4

You could use array_filter:

$filtered = array_filter($mutli, function($v) { return $v['adult'] == 'true'; });
aarox04
  • 98
  • 6
  • excellent, I have stuff like array_filter, but never a callback function. Thanks! – MysteryDev Aug 13 '14 at 19:05
  • @Lenny Doesn't really matter as long as he doesn't compare the types too. Of course it's faster, but as long as he doesn't do that 1 million times, there is no noticeable benefit. – Charlotte Dunois Aug 13 '14 at 19:09
2

If you know the key, you don't need the second foreach.

foreach($multi as $sub) {
    if(!empty($sub['adult']) AND $sub['adult'] == 'true') {
        array_push($list, $sub);
    }
}

edit: I was curious if array_filter is faster than just looping. This is what I got:

Result:

array_filter rendering: 0.30101799964905
foreach rendering: 0.069003820419312

Testscript:

<?php
$mutli = array(
    array('name' => 'john', 'adult' => 'true'  ),
    array('name' => 'eric', 'adult' => 'true'  ),
    array('name' => 'ryan', 'adult' => 'false' )
);

$filtered = array();
$list = array();

$start = microtime(true);
for($i = 1; $i <= 10000; $i++) {
    $filtered = array_filter($mutli, function($v) { return $v['adult'] == true; });
}
echo "array_filter rendering: ".(microtime(true) - $start)."<br />";

$start = microtime(true);
for($i = 1; $i <= 10000; $i++) {
    foreach($mutli as $sub) {
        if(!empty($sub['adult']) AND $sub['adult'] == 'true') {
            array_push($list, $sub);
        }
    }
}
echo "foreach rendering: ".(microtime(true) - $start)."<br />";
Charlotte Dunois
  • 4,638
  • 2
  • 20
  • 39
0

For fun, if you have PHP >= 5.5.0 (needed for array_column):

$result = array_intersect_key($multi,
                              array_keys(array_column($multi, 'adult'), 'true'));
  1. Get the 'adult' column keys and values with array_column
  2. Return the keys and values where the value equals 'true' with array_keys
  3. Return an array where the keys match with the original array with array_intersect
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87