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"}