在数组中反向递归以查找父 ID
Reverse recursive in array to find parent id
正在尝试找出一种获取多维数组中项目的父 ID 的方法:
$Arr = array(
array(
"Id" => 1,
"Parent" => 0,
"Children" => array(
array(
"Id" => 2,
"Parent" => 1,
"Children" => array(),
),
array(
"Id" => 3,
"Parent" => 1,
"Children" => array(
array(
"Id" => 4,
"Parent" => 3,
"Children" => array(),
),
),
),
),
),
array(
"Id" => 5,
"Parent" => 0,
"Children" => array(
array(
"Id" => 6,
"Parent" => 5,
"Children" => array(),
),
),
)
);
我需要为 "Parent" = 0 的顶部元素获取 "Id"。即对于 ID 为 4 的项目,结果应该是 return 1,或者搜索 6 会 return 5。我尝试了各种递归函数的方法,但只有在深度为2.
我找到了这个函数,但它似乎 return 键的名称而不是值:
function find_parent($array, $needle, $parent = null) {
foreach ($array as $key => $value) {
if (is_array($value)) {
$pass = $parent;
if (is_string($key)) {
$pass = $key;
}
$found = find_parent($value, $needle, $pass);
if ($found !== false) {
return $found;
}
} else if ($key === 'Id' && $value === $needle) {
return $parent;
}
}
return false;
}
编辑
以下仅适用于 1 号 level/depth:
function GetParent($Data = array(), $Needle = 0){
foreach($Data as $Key => $Item){
if($Item['Id'] === $Needle && $Item['Parent'] == 0){
return $Item['Id'];
}
if(sizeof($Item['Children']) !== 0)
GetParent($Item['Children'], $Item['Parent']);
}
return false;
}
我不明白我做错了什么。
虽然它通常不是速度高效的,但是 PHP 在 Standard PHP Library (SPL) called Iterators. Anong them you can find RecursiveArrayIterator 中有一个非常好的特性,它可以让您免于自己编写递归函数。在你的情况下,你必须重新定义它的两个方法:
class CustomRecursiveIterator extends RecursiveArrayIterator
{
public function hasChildren() {
return !empty($this->current()['Children']) && is_array($this->current()['Children']);
}
public function getChildren()
{
return new static($this->current()['Children']);
}
}
这样做,你可以确定你会遍历 children,而不是所有数组元素。
鉴于此 class 您可以编写满足您需要的函数:
function getParentId($id, array $array)
{
$iterator = new RecursiveIteratorIterator(
new CustomRecursiveIterator($array),
RecursiveIteratorIterator::CHILD_FIRST
);
$childFound = false;
foreach ($iterator as $item) {
if (
$childFound
&& isset($item['Parent'])
&& $item['Parent'] === 0
&& isset($item['Id'])
) {
return $item['Id'];
}
if (isset($item['Id']) && $item['Id'] === $id) {
$childFound = true;
}
}
return null;
}
注意这个标志RecursiveIteratorIterator::CHILD_FIRST
。
请注意,如果您的数组结构无效,此实现将不起作用。例如,如果有给定 id 的 child,但它没有 zero-parent 的祖先,它将 return 下一个 zero-parent 的元素。
这里是working demo.
正在尝试找出一种获取多维数组中项目的父 ID 的方法:
$Arr = array(
array(
"Id" => 1,
"Parent" => 0,
"Children" => array(
array(
"Id" => 2,
"Parent" => 1,
"Children" => array(),
),
array(
"Id" => 3,
"Parent" => 1,
"Children" => array(
array(
"Id" => 4,
"Parent" => 3,
"Children" => array(),
),
),
),
),
),
array(
"Id" => 5,
"Parent" => 0,
"Children" => array(
array(
"Id" => 6,
"Parent" => 5,
"Children" => array(),
),
),
)
);
我需要为 "Parent" = 0 的顶部元素获取 "Id"。即对于 ID 为 4 的项目,结果应该是 return 1,或者搜索 6 会 return 5。我尝试了各种递归函数的方法,但只有在深度为2.
我找到了这个函数,但它似乎 return 键的名称而不是值:
function find_parent($array, $needle, $parent = null) {
foreach ($array as $key => $value) {
if (is_array($value)) {
$pass = $parent;
if (is_string($key)) {
$pass = $key;
}
$found = find_parent($value, $needle, $pass);
if ($found !== false) {
return $found;
}
} else if ($key === 'Id' && $value === $needle) {
return $parent;
}
}
return false;
}
编辑
以下仅适用于 1 号 level/depth:
function GetParent($Data = array(), $Needle = 0){
foreach($Data as $Key => $Item){
if($Item['Id'] === $Needle && $Item['Parent'] == 0){
return $Item['Id'];
}
if(sizeof($Item['Children']) !== 0)
GetParent($Item['Children'], $Item['Parent']);
}
return false;
}
我不明白我做错了什么。
虽然它通常不是速度高效的,但是 PHP 在 Standard PHP Library (SPL) called Iterators. Anong them you can find RecursiveArrayIterator 中有一个非常好的特性,它可以让您免于自己编写递归函数。在你的情况下,你必须重新定义它的两个方法:
class CustomRecursiveIterator extends RecursiveArrayIterator
{
public function hasChildren() {
return !empty($this->current()['Children']) && is_array($this->current()['Children']);
}
public function getChildren()
{
return new static($this->current()['Children']);
}
}
这样做,你可以确定你会遍历 children,而不是所有数组元素。
鉴于此 class 您可以编写满足您需要的函数:
function getParentId($id, array $array)
{
$iterator = new RecursiveIteratorIterator(
new CustomRecursiveIterator($array),
RecursiveIteratorIterator::CHILD_FIRST
);
$childFound = false;
foreach ($iterator as $item) {
if (
$childFound
&& isset($item['Parent'])
&& $item['Parent'] === 0
&& isset($item['Id'])
) {
return $item['Id'];
}
if (isset($item['Id']) && $item['Id'] === $id) {
$childFound = true;
}
}
return null;
}
注意这个标志RecursiveIteratorIterator::CHILD_FIRST
。
请注意,如果您的数组结构无效,此实现将不起作用。例如,如果有给定 id 的 child,但它没有 zero-parent 的祖先,它将 return 下一个 zero-parent 的元素。
这里是working demo.