php, длинная и глубокая матрица - PullRequest
4 голосов
/ 28 июля 2010

У меня есть глубокий и длинный массив (матрица). Я знаю только идентификатор продукта. Как найти способ продукта?

Пример массива (но, как я уже сказал, он может быть очень длинным и глубоким):

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

У меня есть id: 3, и я хочу получить это: яблоко, старое, 0

Спасибо

Ответы [ 4 ]

1 голос
/ 29 июля 2010

Рекурсия - ответ на этот тип проблемы.Хотя, если мы можем сделать определенные предположения о структуре массива (т. Е. «Id» всегда будет конечным узлом без дочерних элементов), возможны дальнейшие оптимизации:

<?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') );
1 голос
/ 29 июля 2010

Вы можете использовать этого ребенка:

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
)

Сама функция вернет true при успехе и false при ошибке, данные, которые вы хотите получить, будут сохранены в 3-м параметре.

Вы можете использовать array_reverse(), ссылка , чтобы изменить порядок, и array_pop(), ссылка , чтобы удалить последний элемент ('id')

0 голосов
/ 18 апреля 2011

Я попробовал это для моего упражнения по программированию.

<?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);
0 голосов
/ 03 августа 2010

Если вы создадите массив один раз и будете использовать его несколько раз, я бы сделал это по-другому ...


При создании исходного массива создайте еще один

$id_to_info=array();
$id_to_info[1]=&array['apple']['new'][0];
$id_to_info[2]=&array['apple']['new'][2];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...