Question

i have array like below

array('1'=>'parent 1',
      '1.1'=>'1st child of 1',
      '1.2'=>'2nd child of 1',
      '2'=>'parent 2',
      '2.1'=>'1st child of 2',
      '2.2'=>'2nd child of 2',
      '3'=>'parent 3',
      '3.1'=>'1st child of 3',
      '3.2'=>'2nd child of 4'
    )

i need to find out array with parent value like below

 array('1'=>'parent 1',
       '2'=>'parent 2',
      '3'=>'parent 3',
        )

how i can use array filter here?

Était-ce utile?

La solution 2

its possible just a simple tweak

$arr=array('1'=>'parent 1',
      '1.1'=>'1st child of 1',
      '1.2'=>'2nd child of 1',
      '2'=>'parent 2',
      '2.1'=>'1st child of 2',
      '2.2'=>'2nd child of 2',
      '3'=>'parent 3',
      '3.1'=>'1st child of 3',
      '3.2'=>'2nd child of 4'
    );
$f = array_filter(array_keys($arr), function ($k){ return !strpos($k,"."); });
$filter = array_intersect_key($arr, array_flip($f));
print_r($filter);

output

Array ( [1] => parent 1 [2] => parent 2 [3] => parent 3 )

Autres conseils

You'd probably be best to check for the existence of . inside the key, rather than the actual value of the numerous entries, in case the names are changed.

Unfortunately, PHP doesn't provide access to the array key inside an array_filter function. As such, you'd be better to use foreach() and check for the period using strpos():

function parentsOnly($arr)
{
    $retArr = array();

    foreach($arr as $key => $val)
    {
        if(strpos('.', $key) === false)
        {
             $retArr[$key] = $value;
        }
    }

    return $retArr;
}

You can then call the function and assign its result to the array. Something like this:

$parentArray = parentsOnly($array);

If there's no duplication in the array values, and they're all strings:

$result = array_flip(
    array_filter(
        array_flip($myArray),
        function ($value) {
            return strpos('.', $value === false);
        }
    )
);

If you are guaranteed unique values in the array, you could do array_flip to exchange the keys and values, and then array_filter, then array_flip again

$_a = array_flip($a);
$_a = array_filter($_a,function($val){
                         if(false === strpos($val,".")){
                           return true;
                         }
                         return false;
                   });
$a = array_flip($_a);

If not, you could use array_walk to null out the child values, then use array_filter. If null is a possible value for parents (or anything that resolves to false), then you can always choose your own to use for the children, and filter by that. If there isn't such a value you can use, this solution won't work.

$_a = $a;
array_walk($_a,function(&$val,$key){
                         if(false !== strpos($val,".")){
                           $val = null;
                         }
           });
$a = array_filter($_a);

You could also use array_keys, array_filter, and array_intersect_keys. This will work regardless of whether the values are unique, and, unlike the second solution, will work if a parent value is null.

$_a = array_keys($a);
$_a = array_filter($_a,function($val){
                         if(false === strpos($val,".")){
                           return true;
                         }
                         return false;
                   });
$_a = array_flip($_a); //1=>foo, 2=>bar becomes foo=>1, bar=>2
$a = array_intersect_keys($a,$_a);

I know it's often preferable to use array functions when possible, but I'm not sure if any of the above solutions is going to be better than a simple foreach:

$_a = [];
foreach($a as $k=>$v){
  if(false === strpos($k,".")){
    $_a[$k] = $v;
  }
}

However, your original question asked how to use array_filter, so I presented various options for utilizing it. As others have stated, though, if you need to filter based on the value of the key, there is no way to do that with JUST array_filter

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top