【问题标题】:How to build a multidimensional array tree from an associative array in PHP?如何从 PHP 中的关联数组构建多维数组树?
【发布时间】:2019-03-30 20:08:47
【问题描述】:

我正在尝试通过将“s”和“d”键字符串值替换为它们各自的键“bandnumber”数组来从关联数组构建多维数组树,但似乎无法破解它。我只能使它适用于数组的第一个节点。

例如,我有以下数组:

$coiArray = array (
    array('bandnumber' => '02-BELG-2129929', 's'  =>'94-BELG-3237180', 'd' => '96-BELG-3156295' ),
    array('bandnumber' => '94-BELG-3237180', 's'  =>'88-BELG-3206112', 'd' => '88-BELG-3206173' ),
    array('bandnumber' => '88-BELG-3206112', 's'  =>'81-BELG-3238253', 'd' => '87-BELG-3008002' ),
    array('bandnumber' => '88-BELG-3206173', 's'  =>'', 'd' => '' ),
    array('bandnumber' => '96-BELG-3156295', 's'  =>'88-BELG-3206112', 'd' => '85-BELG-3049648' ),
    array('bandnumber' => '85-BELG-3049648', 's'  =>'', 'd' => '' ),
    array('bandnumber' => '81-BELG-3238253', 's'  =>'', 'd' => '' ),
    array('bandnumber' => '87-BELG-3008002', 's'  =>'', 'd' => '' ),
);

我正在尝试以编程方式将上述数组转换为以下多维数组树:

$coiNestedArray = array('bandnumber' => '02-BELG-2129929',
               's' => array('bandnumber' => '94-BELG-3237180',
                     's' => array('bandnumber' => '88-BELG-3206112',
                           's' => array('bandnumber' => '81-BELG-3238253',
                                                 's' =>'',
                                                 'd' => ''
                           ),
                           'd' => array('bandnumber' => '87-BELG-3008002',
                                                 's' =>'',
                                                 'd' => ''
                           )
                     ),
                     'd' => array('bandnumber' => '88-BELG-3206173',
                           's' =>'',
                           'd' => ''
                     )
               ),
               'd' => array('bandnumber' => '96-BELG-3156295',
                     's' => array('bandnumber' => '88-BELG-3206112',
                           's' => array('bandnumber' => '81-BELG-3238253',
                                                 's' =>'',
                                                 'd' => ''
                           ),
                           'd' => array('bandnumber' => '87-BELG-3008002',
                                                 's' =>'',
                                                 'd' => ''
                           )
                     ),
                     'd' => array('bandnumber' => '85-BELG-3049648',
                           's' =>'',
                           'd' => ''
                     )
               )
        );

这是迄今为止我最接近的,但它只更新数组的第一个节点:

function findKey($coiarray, $bandnumber){
    $thisCol = array_column($coiarray, 'bandnumber');
    $found_key = array_search($bandnumber, $thisCol);
    return $found_key;
}


foreach ($coiArray as $key => $value) {

    $s = '';

    $found_key = findKey($coiArray,$coiArray[$key]['s']);
    if(isset($coiArray[$found_key])){
        $s = $coiArray[$found_key];
    }

    $d = '';

    $found_key = findKey($coiArray,$coiArray[$key]['d']);
    if(isset($coiArray[$found_key])) {
        $d = $coiArray[$found_key];
    }

    $coiArray[$key] = array('bandnumber' => $coiArray[$key]['bandnumber'], 's'  => $s, 'd' => $d );

}

我将在此处重新构建数组的整个转储,但这是$coiArray 的第一个节点,来自var_dump($coiArray),您会注意到所有最内层嵌套的 ["s"] 和["d"] 键是字符串而不是它们各自的数组。

[0]=>
  array(3) {
    ["bandnumber"]=>
    string(15) "02-BELG-2129929"
    ["s"]=>
    array(3) {
      ["bandnumber"]=>
      string(15) "94-BELG-3237180"
      ["s"]=>
      string(15) "88-BELG-3206112"
      ["d"]=>
      string(15) "88-BELG-3206173"
    }
    ["d"]=>
    array(3) {
      ["bandnumber"]=>
      string(15) "96-BELG-3156295"
      ["s"]=>
      string(15) "88-BELG-3206112"
      ["d"]=>
      string(15) "85-BELG-3049648"
    }
  }

下面的示例是我手动创建的$coiNestedArray 中的第一个节点,以说明我想要实现的目标。请注意,每个 ["s"] 和 ["d"] 都是一个数组,派生自 $coiArray

array(3) {
  ["bandnumber"]=>
  string(15) "02-BELG-2129929"
  ["s"]=>
  array(3) {
    ["bandnumber"]=>
    string(15) "94-BELG-3237180"
    ["s"]=>
    array(3) {
      ["bandnumber"]=>
      string(15) "88-BELG-3206112"
      ["s"]=>
      array(3) {
        ["bandnumber"]=>
        string(15) "81-BELG-3238253"
        ["s"]=>
        string(0) ""
        ["d"]=>
        string(0) ""
      }
      ["d"]=>
      array(3) {
        ["bandnumber"]=>
        string(15) "87-BELG-3008002"
        ["s"]=>
        string(0) ""
        ["d"]=>
        string(0) ""
      }
    }
    ["d"]=>
    array(3) {
      ["bandnumber"]=>
      string(15) "88-BELG-3206173"
      ["s"]=>
      string(0) ""
      ["d"]=>
      string(0) ""
    }
  }

我该如何解决这个问题?

【问题讨论】:

    标签: php arrays multidimensional-array tree


    【解决方案1】:

    您需要创建一个以波段号为键的关联数组,以便您可以直接按波段号查找行。然后通过引用访问孩子并用该关联数组中的相应值替换每个孩子。

    (可选)检测哪个频段号从未作为子项引用:它是根。但是,如果您知道根波段号,或者您知道它始终是第一个输入行中的那个,那么您可以跳过最后一步。最后提取该根的值(假设正好有一个):

    // Key the rows by their bandnumber:
    foreach($coiArray as $row) {
        $hash[$row["bandnumber"]] = $row;
    }
    foreach($hash as &$row) {
        // Replace children with the corresponding row in the hash
        foreach(["s","d"] as $prop) {
            $child = $row[$prop];
            if (!isset($hash[$child])) continue;
            $row[$prop] =& $hash[$child];
            $children[] = $child; // Keep track of non-root bandnumbers
        }
    }
    // Only needed when you don't know which bandnumber is the root:
    $root = current(array_diff(array_keys($hash), $children, ["s","d"]));
    
    $result = $hash[$root];
    

    【讨论】:

    • 你让它看起来如此微不足道,但它是天才!这几天一直在为此苦苦挣扎。非常感谢!
    • 所以我终于为某人设置了这个,但他们运行的是 PHP 5.3,它不支持数组引用,所以这段代码在 foreach(["s","d"] 和返回“解析错误:语法错误,意外'['”。我将如何重写它以与 php 5.3 兼容?我尝试了 $row["s"] 和 $row["d"] 但没有运气。任何帮助都会不胜感激!提前致谢!
    • 只需首先为该数组定义一个变量:$sd = ["s","d"];,然后对其执行循环:foreach($sd as $prop)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 2011-08-13
    相关资源
    最近更新 更多