2010-07-28 2 views
4

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

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

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

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

Благодаря

+0

Ум, вы имеете в виду вздымающуюся вещь? –

ответ

1

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

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 
) 

самой функцию точны l вернуть true при успешном завершении и false при ошибке данные, которые вы хотите сохранить, будут сохранены в третьем параметре.

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

+0

Ваш выбор «Вы можете использовать этого ребенка:» действительно поразил меня как странное ... – jordanstephens

+0

должен ли я отредактировать его? – Ties

1

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

<?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')); 
+0

вы можете сделать это без 'global' var, и это было бы гораздо лучшим примером, если бы вы это сделали. –

+0

@Mark: Это простой пример - и его можно легко реорганизовать, чтобы вместо этого использовать декларацию переменной 'static $ complete'. Не стесняйтесь публиковать свое собственное решение! – leepowers

-1

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


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


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

Почему я получил -1, мне интересно? –

0

Я попытался это для моего программирования упражнений.

<?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); 
Смежные вопросы