【问题标题】:PHP Recursive Loop using UASORT on Multidimensional Array在多维数组上使用 UASORT 的 PHP 递归循环
【发布时间】:2019-06-14 05:48:11
【问题描述】:

我正在编写一个循环遍历多维数组的脚本,它按预期工作(有点),但我遇到了无法纠正的错误。

我仍然不太习惯构建循环来管理嵌套数组。

这是我的代码。目标是按 sequence 键的值对每一层进行排序,最后我将数组导出为 json。

序列键可能存在也可能不存在于每个子数组中,因此可能需要某种 if 子句

<?php
$list = [
        "key" => "book",
        "sequence" => 1,
        "items" => [
            [
                "key" => "verse",
                "sequence" => 2,
                "items" => [
                    ["sequence" => 3],
                    ["sequence" => 1],
                    ["sequence" => 2],
                ],
            ],
            [
                "key" => "page",
                "sequence" => 1,
                "items" => [
                    [
                        "key" => "page",
                        "sequence" => 2,
                        "items" => [
                            ["sequence" => 2],
                            ["sequence" => 1],
                            ["sequence" => 3],
                        ],
                    ],
                    [
                        "key" => "paragraph",
                        "sequence" => 1,
                        "items" => [
                            ["sequence" => 2],
                            ["sequence" => 1],
                            ["sequence" => 3],
                        ],
                    ],
                ],
            ],
        ],
    ];

function sortit(&$array){

    foreach($array as $key => &$value){
        //If $value is an array.
        if(is_array($value)){

            if($key == "items"){
                uasort($value, function($a,&$b) {
                   return $a["sequence"] <=> $b["sequence"];
                });

            }
            //We need to loop through it.
            sortit($value);
        } else{
            //It is not an array, so print it out.
            echo $key . " : " . $value . "<br/>";
        }
    }
}


sortit($list);

echo "<pre>";

print_r($list);

?>

这是我得到的输出和错误,我想我理解为什么会抛出错误,但同时我无法执行修复错误所需的适当检查。

key : book
sequence : 1
key : page
sequence : 1

E_WARNING : type 2 -- Illegal string offset 'sequence' -- at line 39

E_NOTICE : type 8 -- Undefined index: sequence -- at line 39
sequence : 1
sequence : 2
sequence : 3
sequence : 1
key : page

E_WARNING : type 2 -- Illegal string offset 'sequence' -- at line 39

E_NOTICE : type 8 -- Undefined index: sequence -- at line 39
sequence : 1
sequence : 2
sequence : 3
sequence : 2
key : verse

并不是我很担心,但我想要的另一件事是数组仍按原始顺序构造,即:key, sequence, items

【问题讨论】:

  • 您的数据有点混乱:key =&gt; page 有一个items 数组,它不是二维的,并且与数组中其他地方的格式不匹配。这是数据中唯一的不规则性(除了提到的缺少sequence 键?顺便说一句,缺少sequence 键的数组应该如何排序?你能显示预期的输出吗?
  • @ggorlen 页面数据看起来不错,这是一个疏忽,因为实际数组更深入,所以我创建了这个数组作为测试。我现在正在更新它。至于缺少的序列,通常不会出现这种情况,但可能会有其他不需要序列且不应该排序的数据数组。
  • 啊,我明白了,所以如果他们确实有一个items 键,我们可以保证items 中的所有元素都是具有sequence 键的数组?
  • 是的,没错@ggorlen
  • @ggorlen 我原以为添加子句if($key == "items") 以确保我们正在处理包含sequence 键的当前数组。但由于某种原因,它仍然抛出错误。我认为我对递归循环缺乏了解是让我感到困惑的原因。

标签: php arrays recursion multidimensional-array


【解决方案1】:

使用usort 和数组引用使其变得简单。如果我们正在处理具有集合 item 键的数组,则对 item 数组进行排序并递归其子节点,否则,我们位于叶节点并且可以返回。

function seqSort(&$arr) {
    if (is_array($arr) && array_key_exists("items", $arr)) {
        usort($arr["items"], function ($a, $b) {
            return $a["sequence"] - $b["sequence"];
        });

        foreach ($arr["items"] as &$item) {
            $item = seqSort($item);
        }
    }

    return $arr;
}

结果:

array (
  'key' => 'book',
  'sequence' => 1,
  'items' => 
  array (
    0 => 
    array (
      'key' => 'page',
      'sequence' => 1,
      'items' => 
      array (
        0 => 
        array (
          'key' => 'page',
          'sequence' => 1,
          'items' => 
          array (
            0 => 
            array (
              'sequence' => 1,
            ),
            1 => 
            array (
              'sequence' => 2,
            ),
            2 => 
            array (
              'sequence' => 3,
            ),
          ),
        ),
      ),
    ),
    1 => 
    array (
      'key' => 'verse',
      'sequence' => 2,
      'items' => 
      array (
        0 => 
        array (
          'sequence' => 1,
        ),
        1 => 
        array (
          'sequence' => 2,
        ),
        2 => 
        array (
          'sequence' => 3,
        ),
      ),
    ),
  ),
)

Try it!

请注意,最外面的结构是一个根节点,它不是数组的一部分,无法排序(这可能是无意的,会造成混淆)。

【讨论】:

  • 是的,最外层永远不会有超过一个条目。这是一个很棒的功能,谢谢。我将研究它,希望我能弄清楚你做了什么。
猜你喜欢
  • 2018-12-28
  • 2011-08-30
  • 2021-01-18
  • 1970-01-01
  • 2017-02-26
  • 1970-01-01
  • 1970-01-01
  • 2013-06-25
  • 2019-07-17
相关资源
最近更新 更多