2011-09-14 54 views
0

我知道在多維數組上有很多答案,但是我找不到我準確查找的內容。我是PHP新手,不能完全理解其他一些示例來修改它們。如果有人能指引我,這將是非常感謝。PHP - 根據密鑰名稱從多維數組創建單個數組

外部服務正在向我傳遞以下多維數組。

$mArray = Array (
    [success] => 1 
    [errors] => 0 
    [data] => Array (
    [0] => Array (
     [email] => [email protected] 
     [id] => 123456 
     [email_type] => html 
     [ip_opt] => 10.10.1.1 
     [ip_signup] => 
     [member_rating] => X 
     [info_changed] => 2011-08-17 08:56:51 
     [web_id] => 123456789 
     [language] => 
     [merges] => Array (
     [EMAIL] => [email protected] 
     [NAME] => Firstname 
     [LNAME] => Lastname 
     [ACCOUNT] => ACME Ltd 
     [ACCMANID] => 123456adc 
     [ACCMANTEL] => 1234 123456 
     [ACCMANMAIL] => [email protected] 
     [ACCMANFN] => Humpty 
     [ACCMANLN] => Dumpty 
    ) 
     [status] => unknown 
     [timestamp] => 2011-08-17 08:56:51 
     [lists] => Array () 
     [geo] => Array () 
     [clients] => Array () 
     [static_segments] => Array () 
    ) 
) 
) 

我唯一感興趣的信息是在鍵名下的數組中保存的鍵/值對「合併」。這是關於第三陣列深的。數組的鍵名總是被稱爲合併,但不能保證它在數組中的位置不會被移動。合併數組中的鍵/值對的數量也是可以改變的。

我想我需要的是array_walk_recursive($ mArray,「myfunction」,$ search)的函數;其中$ search包含我正在尋找的鍵名稱(合併)的字符串。它需要遍歷數組直到找到該鍵,檢查它是否包含數組,然後(保留鍵),將每個鍵/值對返回到一個數組中。

因此,爲了清楚起見,該函數的輸出將返回:

$sArray = Array (
     [EMAIL] => [email protected] 
     [NAME] => Firstname 
     [LNAME] => Lastname 
     [ACCOUNT] => ACME Ltd 
     [ACCMANID] => 123456adc 
     [ACCMANTEL] => 1234 123456 
     [ACCMANMAIL] => [email protected] 
     [ACCMANFN] => Humpty 
     [ACCMANLN] => Dumpty 
    ) 

然後我就可以移動到在我的項目,這是密鑰的單一合併數組元素比較下一步從HTML DOM解析器中獲取的ID,並將屬性值替換爲包含在單個數組中的屬性值。

我可能需要一個foreach循環。我知道我可以使用is_array來驗證$ search是否是一個數組。它正在加入我一直在努力的一切。

感謝您的幫助。

回答

0

這裏是一個通用的功能,將工作,它的方式通過一個嵌套的數組,並返回與提供的密鑰中第一次出現相關的值。它允許整數或字符串鍵。如果找不到匹配的鍵,則返回false。

// return the value a key in the supplied array 
function get_keyval($arr,$mykey) 
{ 
    foreach($arr as $key => $value){ 
     if((gettype($key) == gettype($mykey)) && ($key == $mykey)) { 
      return $value; 
     } 
     if(is_array($value)){ 
      return get_keyval($value,$mykey);    
     } 
    } 
    return false; 
} 

// test it out 
$myArray = get_keyval($suppliedArray, "merges"); 
foreach($myArray as $key => $value){ 
    echo "$key = $value\n"; 
} 
+0

謝謝,這工作很好。我查了gettype。如果我理解了這個權利,那麼您確保$ key和$ mykey是相同類型(字符串或數字),然後它們彼此相等(或匹配)? – Dominic

+0

這是對的。如果您嘗試將字符串與數字進行比較,則PHP可以返回錯誤的肯定匹配。 –

+0

更簡單的方法是使用嚴格的比較'==='來防止PHP的類型雜耍。看到這個頁面解釋和演示鬆散比較的潛在問題:https://stackoverflow.com/questions/44426990/type-juggling-while-making-loose-comparison-yields-unwanted-result – mickmackusa

1

這項工作?

function find_merges($arr) 
{ 
    foreach($arr as $key => $value){ 
    if($key == "merges") return $value; 
    if(is_array($value)){ 
     $ret = find_merges($value); 
     if($ret) return $ret; 
    } 
    } 
    return false; 
} 

它會做一個深度優先搜索,直到你要麼跑出鍵或發現一個與價值merges。它不會檢查是否merges是一個數組。嘗試一下,讓我知道如果這有效。

+0

沒有測試,但是遞歸是解決方案。 –

+0

差不多,但並不完全 - 你不能確保'merges'擁有一個數組,它可能是一個空數組,所以你需要做'$ ret!== FALSE'。看到我的回答... – DaveRandom

+0

這對我沒有用。它只是返回原始數組。 – Dominic

0

遞歸函數可以做到這一點。返回失敗時的陣列或FALSE

function search_sub_array ($array, $search = 'merges') { 
    if (!is_array($array)) return FALSE; // We're not interested in non-arrays 
    foreach ($array as $key => $val) { // loop through array elements 
    if (is_array($val)) { // We're still not interested in non-arrays 
     if ($key == $search) { 
     return $val; // We found it, return it 
     } else if (($result = search_sub_array($array)) !== FALSE) { // We found a sub-array, search that as well 
     return $result; // We found it, return it 
     } 
    } 
    } 
    return FALSE; // We didn't find it 
} 

// Example usage 
if (($result = search_sub_array($myArray,'merges')) !== FALSE) { 
    echo "I found it! ".print_r($result,TRUE); 
} else { 
    echo "I didn't find it :-("; 
} 
0

所以你想要訪問數組內的數組?

$mergeArray = NULL; 
foreach($mArray['data'] as $mmArray) 
    $mergeArray[] = $mmArray['merges']; 

這樣的事情?如果merges總是深入三層,我不明白爲什麼你需要遞歸。否則,請參閱其他答案。

+0

謝謝,但我不能保證'合併'將永遠是三下深。我認爲遞歸對於任何變化都是最靈活的。 – Dominic

0

下面是另一種方法,主要是因爲我今天還沒有用完我的迭代器配額。

$search = new RegexIterator(
    new RecursiveIteratorIterator(
     new ParentIterator(new RecursiveArrayIterator($array)), 
     RecursiveIteratorIterator::SELF_FIRST), 
    '/^merges$/D', RegexIterator::MATCH, RegexIterator::USE_KEY 
); 
$search->rewind(); 
$merges = $search->current(); 
0

array_walk_recursive()非常適合這項工作!它並不關心鍵值對的級別,它只是迭代「葉節點」,因此不需要檢查一個元素是否包含字符串。在函數內部,我只是比較鍵與數組針之間的關係,以生成一維結果數組($sArray)。

要清楚,我假設您在merges子陣列中有可預測的鍵。

代碼:(Demo

$needles=['EMAIL','NAME','LNAME','ACCOUNT','ACCMANID','ACCMANTEL','ACCMANMAIL','ACCMANFN','ACCMANLN']; 
array_walk_recursive($mArray,function($v,$k)use(&$sArray,$needles){if(in_array($k,$needles))$sArray[$k]=$v;}); 
var_export($sArray); 

輸出:

array (
    'EMAIL' => '[email protected]', 
    'NAME' => 'Firstname', 
    'LNAME' => 'Lastname', 
    'ACCOUNT' => 'ACME Ltd', 
    'ACCMANID' => '123456adc', 
    'ACCMANTEL' => '1234 123456', 
    'ACCMANMAIL' => '[email protected]', 
    'ACCMANFN' => 'Humpty', 
    'ACCMANLN' => 'Dumpty', 
)