user319854
user319854

Reputation: 4106

php, long and deep matrix

I have a deep and long 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

Upvotes: 4

Views: 223

Answers (4)

kamawanu
kamawanu

Reputation: 11

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);

Upvotes: 0

vlad b.
vlad b.

Reputation: 695

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];

Upvotes: -1

Ties
Ties

Reputation: 5846

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')

Upvotes: 1

leepowers
leepowers

Reputation: 38308

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') );

Upvotes: 1

Related Questions