2011-09-14 57 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', 
)