2016-08-10 35 views
3

我有Array結構$array在PHP中查找層級結構中的父級密鑰

Array 
    (
     [WIDGET_BUILDER_CREATE] => Array 
     (
     [TITLE] => Widget Builder 
     [WIDGET_TYPE_LBL] => Select Widget Type 
     [RANGE_LBL] => Select Range 
     [RANGE_TYPE_LBL] => Select Range Type 
     [TOP_SERVICE_CHKBOX] => Top Services 
     [SR_STATE_LBL] => Select Sr States 
     [SR_TYPE_LBL] => Select Sr Types 
     [SR_CATEGORY_LBL] => Select Sr Categories 
     [SR_SOURCE_LBL] => Select Sources 
     [SR_PROVIDER_LBL] => Select Sr Provider 
     [ADDRESS] => Enter Address 
     [SUBMIT_BTN] => Generate Data 
     [CHART_DIV] => Array 
      (
       [TYPE] => Select chart type 
       [SAVE_BTN] => Save Widget 
       [SERIES_NAME] => Change Parameters 
       [PARA_DIALOG] => Array 
        (
         [TITLE] => Chart Parameters 
         [SERIESNAME] => Series Name 
         [YAXISNAME] => Y axies name 
         [VALIDATION] => Array 
          (
           [SERIESNAME] => Please enter series name 
           [YAXISNAME] => Please enter y axis name 
          ) 

         [SAVE_BTN] => Save 
         [CANCEL_BTN] => Cancel 
        ) 

       [SAVE_DIALOG] => Array 
        (
         [TITLE] => Save Chart 
         [CHART_NAME] => Chart Name 
         [SHOW_TO_USER] => System Widget 
         [VALIDATION] => Array 
          (
           [CHART_NAME] => Please enter chart name 
          ) 

         [SAVE_BTN] => Save 
         [CANCEL_BTN] => Cancel 
        ) 

      ) 

     [GRID_DIV] => Array 
      (
      ) 

    ) 

) 

問題:

我想在PHP建立一個function一樣,如果我進入一個value,那麼它應該在層次結構中返回所有parent keys

比方說,例如,如果我進入Please enter y axis name,它應該返回作爲

$array['WIDGET_BUILDER_CREATE']['CHART_DIV']['PARA_DIALOG']['VALIDATION']['YAXISNAME']; 

編輯:我試着像How to get hierarchy path of an element in an Array但它返回一個字符串,但我想爲array key indexed。這意味着

print_r($array['WIDGET_BUILDER_CREATE']['CHART_DIV']['PARA_DIALOG']['VALIDATION']['YAXISNAME']); 

//returns Please enter y axis name 

我使用PHP 5.5.9

+0

我不明白。該函數應返回您輸入的相同值?在你的示例中,'$ array ['WIDGET_BUILDER_CREATE'] ...'實際上會返回字符串'「請輸入y軸名稱」 – BeetleJuice

+0

我認爲海報希望函數返回包含字符串而不是值。 – SheppardDigital

+0

我想要數組路徑 – Hiranya

回答

0

如果你感覺就像你可以使用一個快速&髒方法,你可以試試下面該function使用嵌套foreach循環。但是,如果你感到怪異,你可以簡單地重構自己的嵌套循環,並將它們變成一個更短的遞歸算法。爲了測試這個快速&髒方法,去here

示例數據:

<?php 

    $array = [ 
     'WIDGET_BUILDER_CREATE' => [ 
      "TITLE"     => "Widget Builder", 
      "WIDGET_TYPE_LBL"  => "Select Widget Type", 
      "RANGE_LBL"    => "Select Range", 
      "RANGE_TYPE_LBL"  => "Select Range Type", 
      "TOP_SERVICE_CHKBOX" => "Top Services", 
      "SR_STATE_LBL"   => "Select Sr States", 
      "SR_TYPE_LBL"   => "Select Sr Types", 
      "SR_CATEGORY_LBL"  => "Select Sr Categories", 
      "SR_SOURCE_LBL"   => "Select Sources", 
      "SR_PROVIDER_LBL"  => "Select Sr Provider", 
      "ADDRESS"    => "Enter Address", 
      "SUBMIT_BTN"   => "Generate Data", 
      "CHART_DIV"    => [ 
       "TYPE"   => "Select chart type", 
       "SAVE_BTN"  => "Save Widget", 
       "SERIES_NAME" => "Change Parameters", 
       "PARA_DIALOG" => [ 
        "TITLE"   => "Chart Parameters", 
        "SERIESNAME" => "Series Name", 
        "YAXISNAME"  => "Y axies name", 
        "VALIDATION" => [ 
         "SERIESNAME" => "Please enter series name", 
         "YAXISNAME"  => "Please enter y axis name", 

        ], 
        "SAVE_BTN"   => "Save", 
        "CANCEL_BTN"  => "Cancel", 
       ], 
       "SAVE_DIALOG" =>[ 
        "TITLE"   => "Save Chart", 
        "CHART_NAME" => "Chart Name", 
        "SHOW_TO_USER" => "System Widget", 
        "VALIDATION" => [ 
         "CHART_NAME" => "Please enter chart name", 
        ], 
        "SAVE_BTN"  => "Save", 
        "CANCEL_BTN" => "Cancel", 
       ], 

      ], 
      "GRID_DIV"    => [], 
     ], 
    ]; 

快速& DIRTY功能:

<?php 

    function keywordLookUp(array $array, $keyWord, $arrayName="\$array"){ 
     $route = $mainKey = null; $arrRte = $arrResult = []; 
     foreach($array as $intKey=>$item){ 
      $mainKey = $route = "{$arrayName}['{$intKey}']"; 
      if(is_array($item)){ 
       foreach($item as $iKey=>$innerItem){ 
        if($lKey = array_search($keyWord, $item)){ 
         $route .= $s = "['$lKey']"; break; 
        } 
        if(is_array($innerItem)){ 
         foreach($innerItem as $iKey2=>$innerItem2){ 
          if($lKey = array_search($keyWord, $innerItem)){ 
           if(isset($s)){ 
           if(! array_search($route, $arrRte)){$arrRte[] = $route;} 
            $arrRte[] = "{$s}['$lKey']"; 
            $route .= "\n{$s}['$lKey']"; 
           }else{ 
            $route .= "['$iKey']['$lKey']"; 
           } $s  = str_replace("['$lKey']", "", $route); break; 
          } 
          if(is_array($innerItem2)){ 
           foreach($innerItem2 as $iKey3=>$innerItem3){ 
            if($lKey = array_search($keyWord, $innerItem2)){ 
             if(isset($s)){ 
              if(! array_search($route, $arrRte)){$arrRte[] = $route;} 
              $arrRte[] ="{$s}['$iKey2']['$lKey']"; 
              $route .= "\n{$s}['$iKey2']['$lKey']"; 
             }else{ 
              $route .= "['$iKey']['$iKey2']['$lKey']"; 
             } $s  = str_replace("['$iKey2']['$lKey']", "", $route); break; 
            } 
            if(is_array($innerItem3)){ 
             foreach($innerItem3 as $iKey4=>$innerItem4){ 
              if($lKey = array_search($keyWord, $innerItem3)){ 
               if(isset($s)){ 
                if(! array_search($route, $arrRte)){$arrRte[] = $route;} 
                $arrRte[] = "{$s}['$iKey3']['$lKey']"; 
                $route .= "\n{$s}['$iKey3']['$lKey']"; 
               }else{ 
                $route .= "['$iKey']['$iKey2']['$iKey3']['$lKey']"; 
               }break; 
              } 
             } 
            } 
           } 
          } 
         } 
        } 
       } 
      } 
     } 

     $fin = ($route == $mainKey) ? null : $route; 
     $fin = (!empty($arrRte) && sizeof($arrRte > 1))?$arrRte:$fin; 
     return $fin; 
    } 

    $path = keywordLookUp($array, "Please enter y axis name"); 
    $path2 = keywordLookUp($array, "Chart Parameters"); 
    $path3 = keywordLookUp($array, "Cancel"); 

    var_dump($path); 
    // PRODUCES:: string '$array['WIDGET_BUILDER_CREATE']['CHART_DIV']['PARA_DIALOG']['VALIDATION']['SERIESNAME']' (length=87) 

    var_dump($path2); 
    // PRODUCES:: string '$array['WIDGET_BUILDER_CREATE']['CHART_DIV']['PARA_DIALOG']['TITLE']' (length=68) 

    var_dump($path3); 
    // PRODUCES:: 
    array (size=2) 
     0 => string '$array['WIDGET_BUILDER_CREATE']['CHART_DIV']['PARA_DIALOG']['CANCEL_BTN']' (length=73) 
     1 => string '$array['WIDGET_BUILDER_CREATE']['CHART_DIV']['SAVE_DIALOG']['CANCEL_BTN']' (length=73) 
+0

該解決方案不包含頂級密鑰。由於您對深度進行了硬編碼,因此它也不支持深度嵌套數組。最後,OP說如果有多個匹配路徑,函數應該返回一個包含所有這些路徑的數組,這是不行的。儘管這是一個有趣的方法。 – BeetleJuice

+0

@ BeetleJuice非常感謝您指出了這一點,但我認爲您應該注意到以下幾點:*** Quick&Dirty ***和***如果您感覺令人討厭,您可以簡單地重構嵌套循環你自己的,並把它們變成一個更短的遞歸算法***。是的,它不支持深度嵌套結構,這就是爲什麼我提到,OP被要求實現的遞歸算法....不過,謝謝... – Poiz

+0

@Hiranya當然...郵政剛剛更新以包括...建議你考慮實施一個遞歸算法,如果你的數組深度超過4級...... – Poiz

1

下面的函數搜索$source陣列和與用於$target值所有匹配的路徑返回一個數組。如果在$source中找不到該值,它將返回一個空數組。

function pathFinder($target, array $source, $parentPath=''){ 
    $results=[]; 
    foreach($source as $k => $v){ 
     $path = $parentPath.'/'.$k; //current path 
     //if element is array, recurse and import found results 
     if(is_array($v) && $result=pathFinder($target, $v,$path)){ 
      foreach($result as $r) array_push($results,$r); 
     } 
     //else add element to results if it matches $target 
     elseif($v===$target) $results[]=$path;  
    } 
    return $results; 
} 

用法:

$target = 'Please enter axis Y name'; 
$foundPaths = pathFinder($target, $array); 

Live demo

+0

它返回'/ WIDGET_BUILDER_CREATE/CHART_DIV/PARA_DIALOG/VALIDATION/YAXISNAME',但不是'數組索引' – Hiranya

+0

@Hiranya所以我爲你做了很難的部分。當然你可以做其餘的事情。只要在'$ path = $ parentPath。'/'。$ k;'這行就可以按照你的意願格式化路徑。或者只是通過'explode('/',$ result)'來格式化函數返回的路徑,然後在每個結果周圍添加括號'[]'。如果您選擇將我的答案作爲解決方案的基礎,請不要忘記加註並選擇它。 – BeetleJuice