Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 找到合适的子级后,如何在多维数组中导航备份?_Php_Arrays_Multidimensional Array - Fatal编程技术网

Php 找到合适的子级后,如何在多维数组中导航备份?

Php 找到合适的子级后,如何在多维数组中导航备份?,php,arrays,multidimensional-array,Php,Arrays,Multidimensional Array,我有一个如下所示的数组: RecursiveArrayIterator {#605 ▼ +"xs:schema": array:2 [▼ "value" => array:1 [▼ "xs:element" => array:2 [▼ "value" => array:1 [▼ "xs:complexType" => array:2 [▼ "value" => array:2 [▼

我有一个如下所示的数组:

RecursiveArrayIterator {#605 ▼
  +"xs:schema": array:2 [▼
    "value" => array:1 [▼
      "xs:element" => array:2 [▼
        "value" => array:1 [▼
          "xs:complexType" => array:2 [▼
            "value" => array:2 [▼
              "xs:sequence" => array:2 [▼
                "value" => array:1 [▼
                  "xs:element" => array:3 [▼
                    0 => array:2 [▼
                      "value" => array:1 [▼
                        "xs:simpleType" => array:2 [▼
                          "value" => array:1 [▼
                            "xs:restriction" => array:2 [▼
                              "value" => array:1 [▼
                                "xs:maxLength" => array:1 [▼
                                  "attributes" => array:1 [▼
                                    "value" => "40"
                                  ]
                                ]
                              ]
                              "attributes" => array:1 [▶]
                            ]
                          ]
                          "attributes" => []
                        ]
                      ]
                      "attributes" => array:1 [▼
                        "name" => "title"
                      ]
                    ]
                    1 => array:2 [▶]
                    2 => array:2 [▶]
                  ]
                ]
                "attributes" => []
              ]
              "xs:attribute" => array:2 [▶]
            ]
            "attributes" => []
          ]
        ]
        "attributes" => array:1 [▼
          "name" => "book"
        ]
      ]
    ]
    "attributes" => []
  ]
}
我需要访问
xs:maxLength
属性,为此,我使用以下方法:

private function findRestrictions(array $haystack, $needle)
{
    $iterator = new \RecursiveArrayIterator($haystack);
    $recursive = new \RecursiveIteratorIterator(
        $iterator,
        \RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ($recursive as $key => $value)
    {
        if ($key === $needle)
        {
            return (int)$value['attributes']['value'];
        }
    }
}

$maxLength = findRestrictions($array, 'xs:maxLength');

所以这给了我40分,就像预期的一样。无论如何,我的问题是我需要知道这个限制属于哪个元素,这在
xs:element[0]['attributes']['name']
中提到过,我不确定如何到达那里获取我需要的信息,基于
xs:maxLength

的匹配,我认为我已经编写了一个相当好的解决方案,这次是测试

我的示例阵列:

$array = [
        "we" => 
            ["are" => [
                "lorem" => [
                    "gone" => "away",
                    "my" => "friend"
                    ],
                "never" => "abcd",
                "any" => [
                        "btc" => "abc",
                        "help" => [
                            "mqf" => "bmx"
                            ]
                    ]
                ]
            ],
         "fancy" => [
                "lorem" => [
                    "gone" => "away",
                    "my" => "friend"
                    ],
                "never" => "abcd",
                "any" => [
                        "btc" => "abc",
                        "help" => [
                            "mqf" => "bmx",
                            "abc" => 13
                            ]
                    ]
                ],
         "beer" => "bar",
         "helpful" => [
                "meta" => "column",
                "gamma" => [
                    "lorem" => [
                        "gone" => "mad",
                        "my" => "drink"
                        ],
                    "never" => "abcd",
                    "any" => [
                            "btc" => "abc",
                            "help" => [
                                "mqf" => "bmx",
                                "abc" => "alot"
                                ]
                        ]
                    ]
             ],
          "elements" => [
                0 => 88,
                1 => 99
              ]
        ];
我的解决方案:

    function array_find_value_return_parent($array,$needle,$parentkey) {
        $iterator = new RecursiveIteratorIterator(
            new RecursiveArrayIterator($array),
            RecursiveIteratorIterator::SELF_FIRST);

        foreach($iterator as $key => $value) {
            if($value === $needle) {
                for ($i = $iterator->getDepth() - 1; $i >= 0; $i--) {
                    if($iterator->getSubIterator($i)->key() === $parentkey) {
                        return $iterator->getSubIterator($i)->current();
                    }
                }
            }
        }
    }

    function array_find_key_return_value($array,$findkey) {
        $iterator = new RecursiveIteratorIterator(
            new RecursiveArrayIterator($array),
            RecursiveIteratorIterator::SELF_FIRST);

        foreach($iterator as $key => $value) {
            if($findkey === $key) {
               return $iterator->current();
            }
        }
    }
我的测试:

    $findvalue = "alot";
    $findparentkey = "gamma";
    $findreturnkey = "gone";

   echo array_find_key_return_value(array_find_value_return_parent($array,$findvalue,$findparentkey),$findreturnkey);
输出:mad

对于您的情况,这意味着您可以执行以下操作:

    $findvalue = "40";
    $findparentkey = "xs:element";
    $findreturnkey = "name";

   echo array_find_key_return_value(array_find_value_return_parent($array,$findvalue,$findparentkey),$findreturnkey);
预期产出:标题


对吗?

我不知道您的原始数据结构,所以我只是将您的数据转换为PHP数组。您可以使用
$aks=newarraykeysearcher($data,'xs:maxLength')
以查找所需的密钥。您可以使搜索更加复杂,以满足您的需求

但是,如果您使用的是XML之类的东西,强烈建议使用基于XML的解决方案,如XPath查询(例如:,)。这些方法更容易使用,更快,更准确

<?php

$data =  [
"xs:schema"=>  [
    "value" =>  [
      "xs:element" =>  [
        "value" =>  [
          "xs:complexType" =>  [
            "value" =>  [
              "xs:sequence" =>  [
                "value" =>  [
                  "xs:element" =>  [
                    0 =>  [
                      "value" =>  [
                        "xs:simpleType" =>  [
                          "value" =>  [
                            "xs:restriction" =>  [
                              "value" =>  [
                                "xs:maxLength" =>  [
                                  "attributes" =>  [
                                    "value" => "40"
                                  ]
                                ]
                              ],
                              "attributes" =>  []
                            ]
                          ],
                          "attributes" => []
                        ]
                      ],
                      "attributes" =>  [
                        "name" => "title"
                      ]
                    ],
                    1 =>  [],
                    2 =>  [],
                  ]
                ],
                "attributes" => []
              ],
              "xs:attribute" =>  []
            ],
            "attributes" => []
          ]
        ],
        "attributes" =>  [
          "name" => "book"
        ]
      ]
    ],
    "attributes" => []
  ]
];


class ArrayKeySearcher
{
    public $data;
    public $path;
    public $value;

    public function __construct($data, $key)
    {
        $this->data = $data;
        $this->findKeyPath($data, $key);
    }

    private function findKeyPath($data, $key)
    {
        foreach ($data as $k => $v) {
            $this->path[] = $k;
            if ($key === $k) {
                $this->value = $v;
                return;
            }
            $this->findKeyPath($v, $key);
            if (!is_null($this->value))
                return;
            array_pop($this->path);
        }
    }

    public function arrayReverseSearch($a, $k, $pos = null)
    {
        $count = count($a);
        $i = ($pos === null) ? ($count - 1) : $pos;
        for(; $i >= 0; $i--) {
            if($a[$i] === $k)
                return $i;
        }
        return $i;
    }

    public function getValueByPath($path)
    {
        $v = $this->data;
        foreach($path as $k) {
            if(isset($v[$k]))
                $v = $v[$k];
        }
        return $v;
    }
}


$aks = new ArrayKeySearcher($data, 'xs:maxLength');
echo 'path: ' . json_encode($aks->path) . PHP_EOL;
echo 'value: ' . json_encode($aks->value) . PHP_EOL;

$p = $aks->path;
$pos = $aks->arrayReverseSearch($p, 'xs:simpleType');
$pos = $aks->arrayReverseSearch($p, 'value', $pos);
$p = array_slice($p, 0, $pos);
$parent = $aks->getValueByPath($p);
echo 'parent path: ' . json_encode($p) . PHP_EOL;
echo 'parent attributes: ' . json_encode($parent['attributes']) . PHP_EOL;

这看起来像XML,您考虑过使用XPath吗?它能够根据某些条件获取元素(在您的情况下,它将是最大值)。性能可能不是最好的,但为了确保它应该根据您的迭代器方法进行测试。我只能回应@sevavietl的评论,使用PHP的XML工具在您的模式中导航非常有意义@salath你能把它作为一个答案发布,这样我就可以接受它吗?@salath有没有办法安全地找到实际XML字符串中的元素,这样我就可以应用最大/最小长度限制?这一条看起来相当棘手,因为XML上可能有同一标记的多个元素处于不同的级别,这可能会导致我将限制应用到错误的节点。@中止我的评论并不是问题的真正答案,它明确要求使用多维数组。它更适合于一个全新的问题。至于查找与限制不匹配的元素,这听起来很像是试图根据模式验证XML文档,然后再次验证。
path: ["xs:schema","value","xs:element","value","xs:complexType","value","xs:sequence","value","xs:element",0,"value","xs:simpleType","value","xs:restriction","value","xs:maxLength"]
value: {"attributes":{"value":"40"}}
parent path: ["xs:schema","value","xs:element","value","xs:complexType","value","xs:sequence","value","xs:element",0]
parent attributes: {"name":"title"}