开发者

php, long and deep matrix

I have a deep and lo开发者_StackOverflow中文版ng array (matrix). I only know the product ID. How found way to product?

Sample an array of (but as I said, it can be very long and deep):

Array(
        [apple] => Array(
                [new] => Array(
                        [0] => Array([id] => 1)
                        [1] => Array([id] => 2))
                [old] => Array(
                        [0] => Array([id] => 3)
                        [1] => Array([id] => 4))
            )
)

I have id: 3, and i wish get this: apple, old, 0

Thanks


You can use this baby:

function getById($id,$array,&$keys){
  foreach($array as $key => $value){
     if(is_array( $value )){
        $result = getById($id,$value,$keys);
        if($result == true){
          $keys[] = $key;
          return true;
        }
     }
     else if($key == 'id' && $value == $id){
       $keys[] = $key; // Optional, adds id to the result array
       return true;
     }
  }
  return false;
}
// USAGE:
$result_array = array();
getById( 3, $products, $result_array);
// RESULT (= $result_array)
Array
(
    [0] => id
    [1] => 0
    [2] => old
    [3] => apple
)

The function itself will return true on success and false on error, the data you want to have will be stored in the 3rd parameter.

You can use array_reverse(), link, to reverse the order and array_pop(), link, to remove the last item ('id')


Recursion is the answer for this type of problem. Though, if we can make certain assumptions about the structure of the array (i.e., 'id' always be a leaf node with no children) there's further optimizations possible:

<?php
$a = array(
    'apple'=> array(
        'new'=> array(array('id' => 1), array('id' => 2), array('id' => 5)),
        'old'=> array(array('id' => 3), array('id' => 4, 'keyname' => 'keyvalue'))
    ),
);

// When true the complete path has been found.
$complete = false;

function get_path($a, $key, $value, &$path = null) {
    global $complete;
    // Initialize path array for first call
    if (is_null($path)) $path = array();
    foreach ($a as $k => $v) {
        // Build current path being tested
        array_push($path, $k);
        // Check for key / value match
        if ($k == $key && $v == $value) {
            // Complete path found!
            $complete= true;
            // Remove last path
            array_pop($path);
            break;
        } else if (is_array($v)) {
            // **RECURSION** Step down into the next array
            get_path($v, $key, $value, $path);
        }
        // When the complete path is found no need to continue loop iteration
        if ($complete) break;
        // Teardown current test path
        array_pop($path);
    }
    return $path;
}

var_dump( get_path($a, 'id', 3) );
$complete = false;
var_dump( get_path($a, 'id', 2) );
$complete = false;
var_dump( get_path($a, 'id', 5) );
$complete = false;
var_dump( get_path($a, 'keyname', 'keyvalue') );


I tried this for my programming exercise.

<?php

$data = array(
    'apple'=> array(
        'new'=> array(array('id' => 1), array('id' => 2), array('id' => 5)),
        'old'=> array(array('id' => 3), array('id' => 4))
    ),
);

####print_r($data);

function deepfind($data,$findfor,$depth = array() ){
    foreach( $data as $key => $moredata ){
        if( is_scalar($moredata) && $moredata == $findfor ){
            return $depth;
        } elseif( is_array($moredata) ){
            $moredepth = $depth;
            $moredepth[] = $key;
            $isok = deepfind( $moredata, $findfor, $moredepth );
            if( $isok !== false ){
                return $isok;
            }
        }
    }
    return false;
}

$aaa = deepfind($data,3);
print_r($aaa);


If you create the array once and use it multiple times i would do it another way...


When building the initial array create another one


$id_to_info=array();
$id_to_info[1]=&array['apple']['new'][0];
$id_to_info[2]=&array['apple']['new'][2];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜