遍历&更改多维php数组中的子键

发布于 2024-12-07 10:16:45 字数 1090 浏览 0 评论 0原文

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

Array(
  [135] => Array(
    [150] => Array(
      [151] => Array(
        [1]   => Array()
        [153] => Array()
      )
      [1] => Array(
        [1] => Array()
        [2] => Array()
      )
    )
    [1] => Array(
      [1] => Array(
        [1] => Array()
        [2] => Array()
      )
      [2] => Array(
        [1] => Array()
        [2] => Array()
      )
    )
  )
)

我想更改为以下内容:

Array(
  [135] => Array(
    [150|135] => Array(
      [151|150] => Array(
        [1|151]   => Array()
        [153|151] => Array()
      )
      [1|150] => Array(
        [1|1] => Array()
        [2|1] => Array()
      )
    )
    [1|135] => Array(
      [1|1] => Array(
        [1|1] => Array()
        [2|1] => Array()
      )
      [2|1] => Array(
        [1|2] => Array()
        [2|2] => Array()
      )
    )
  )
)

我的意思是每个子键都会有 his key |父密钥 格式。树标签是固定的。深度不会比上面代码中显示的更多或更少。

最好的方法是什么?感谢您的帮助

I have an multidimensional array that looks like this:

Array(
  [135] => Array(
    [150] => Array(
      [151] => Array(
        [1]   => Array()
        [153] => Array()
      )
      [1] => Array(
        [1] => Array()
        [2] => Array()
      )
    )
    [1] => Array(
      [1] => Array(
        [1] => Array()
        [2] => Array()
      )
      [2] => Array(
        [1] => Array()
        [2] => Array()
      )
    )
  )
)

I would like to change to the following:

Array(
  [135] => Array(
    [150|135] => Array(
      [151|150] => Array(
        [1|151]   => Array()
        [153|151] => Array()
      )
      [1|150] => Array(
        [1|1] => Array()
        [2|1] => Array()
      )
    )
    [1|135] => Array(
      [1|1] => Array(
        [1|1] => Array()
        [2|1] => Array()
      )
      [2|1] => Array(
        [1|2] => Array()
        [2|2] => Array()
      )
    )
  )
)

I mean each child key will have his key | parent key format. Tree label is fixed. No more or less depth than shown in the above code.

What is the best way to do this? Thank you for any assistance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青芜 2024-12-14 10:16:45

试试这个:

    $arr = Array ( [135] => Array ( [150] => Array ( [151] => Array ( [1] => Array ( )))));

foreach($arr as $key1 => $value1)
{
    if(is_array($value1))
    {
        foreach($value1 as $key2 => $value2)
        {
            if(is_array($value2))
            {
                  foreach($value2 as $key3 => $value3)
                  {
                      if(is_array($value3))
                      {
                          foreach($value3 as $key4 => $value4)
                          {
                              if(is_array($value4))
                              {
                                   foreach($value4 as $key5 => $value5)
                                   {
                                        $value4[$key5.'|'.$key4] = $value5;
                                        unset($value4[$key5]);
                                   }
                              }
                              else
                              {
                                   $value3[$key4.'|'.$key3] = $value4;
                                   unset($value3[$key4]);
                              }
                          }                          
                       }
                       else
                       {
                           $value2[$key3.'|'.$key2] = $value3;
                           unset($value2[$key3]);
                       }
                  }
            }
            else
            {
                 $value1[$key2.'|'.$key1] = $value2;
                 unset($value1[$key2]);
            }
        }
    }
}

我认为这可以给你一些想法,但我还没有测试过,所以我不太确定正确性。

Try this:

    $arr = Array ( [135] => Array ( [150] => Array ( [151] => Array ( [1] => Array ( )))));

foreach($arr as $key1 => $value1)
{
    if(is_array($value1))
    {
        foreach($value1 as $key2 => $value2)
        {
            if(is_array($value2))
            {
                  foreach($value2 as $key3 => $value3)
                  {
                      if(is_array($value3))
                      {
                          foreach($value3 as $key4 => $value4)
                          {
                              if(is_array($value4))
                              {
                                   foreach($value4 as $key5 => $value5)
                                   {
                                        $value4[$key5.'|'.$key4] = $value5;
                                        unset($value4[$key5]);
                                   }
                              }
                              else
                              {
                                   $value3[$key4.'|'.$key3] = $value4;
                                   unset($value3[$key4]);
                              }
                          }                          
                       }
                       else
                       {
                           $value2[$key3.'|'.$key2] = $value3;
                           unset($value2[$key3]);
                       }
                  }
            }
            else
            {
                 $value1[$key2.'|'.$key1] = $value2;
                 unset($value1[$key2]);
            }
        }
    }
}

I think this can give you some idea but i have not tested this so i am not very sure about the correctness.

游魂 2024-12-14 10:16:45

不需要疯狂的嵌套 foreach() 循环来解决这个问题。递归是你的朋友:

function get_fancy_array($arr, $parent_id=null) {
  $fancy_arr = array();

  // turn e.g. 'parent' or 'parent|child' into '|parent' and NULL into ''
  $parent_id_sufx = $parent_id === null ?
    '' : '|' . explode('|', (strint)$parent_id, 1)[0];

  foreach($arr as $key => $val) {
    $key = (string)$key . $parent_id_sufx;

    if( is_array($val) ) {
      // it's an array, so recursively do the same thing at the next level
      $fancy_array[$key] = get_fancy_arr($val, $key);
    } else {
      $fancy_array[$key] = $val;
    }
  }

  return $fancy_arr;
}

// Usage:
$arr = array( /* your big nested array here */ );

$fancier_arr = get_fancy_array($arr);
print_r($fancier_arr);

There's no need for crazy nested foreach() loops to solve this. Recursion is your friend:

function get_fancy_array($arr, $parent_id=null) {
  $fancy_arr = array();

  // turn e.g. 'parent' or 'parent|child' into '|parent' and NULL into ''
  $parent_id_sufx = $parent_id === null ?
    '' : '|' . explode('|', (strint)$parent_id, 1)[0];

  foreach($arr as $key => $val) {
    $key = (string)$key . $parent_id_sufx;

    if( is_array($val) ) {
      // it's an array, so recursively do the same thing at the next level
      $fancy_array[$key] = get_fancy_arr($val, $key);
    } else {
      $fancy_array[$key] = $val;
    }
  }

  return $fancy_arr;
}

// Usage:
$arr = array( /* your big nested array here */ );

$fancier_arr = get_fancy_array($arr);
print_r($fancier_arr);
蓝戈者 2024-12-14 10:16:45

您完全可以按照您的要求进行操作:遍历并更改密钥(演示):

/**
 * traverse array and
 * add parent key to children key
 * 
 * @param array $a (return)
 * @param int $p (optional) parent key 
 */
function changeKeys(array &$a, $p = null)
{
    static $f = __FUNCTION__;

    foreach($a as $k => &$v)
    {
        # test if already processed
        if (is_string($k))
            return;

        # traverse children if children exists
        if ($v)
            $f($v, $k);        

        # rename key if parent exists
        if ($p)
        {
            $a["$k|$p"] = &$v;            
            unset($a[$k]);
        }
    }
}

此函数使用递归进行遍历(该函数调用本身),因此它仍然可以在多个级别上运行。

更改数组键实际上是不可能的,没有像 array_rename_key 之类的功能。相反,将添加具有新密钥的项目,然后删除具有旧密钥的项目。为了不重复值,在上面的示例中使用了引用/别名:

$a["$k|$p"] = &$v;            
unset($a[$k]);

$a 是数组,$v 是当前元素的值,>$k 密钥和 $p 父级密钥。

当新元素添加到数组末尾时,在 foreach 内部需要检查是否已处理某个键(这是一个新键,所有新键都是字符串)以退出。

You can exactly do like you asked: Traverse and change keys (Demo):

/**
 * traverse array and
 * add parent key to children key
 * 
 * @param array $a (return)
 * @param int $p (optional) parent key 
 */
function changeKeys(array &$a, $p = null)
{
    static $f = __FUNCTION__;

    foreach($a as $k => &$v)
    {
        # test if already processed
        if (is_string($k))
            return;

        # traverse children if children exists
        if ($v)
            $f($v, $k);        

        # rename key if parent exists
        if ($p)
        {
            $a["$k|$p"] = &$v;            
            unset($a[$k]);
        }
    }
}

This function traverses with recursion (the function calls itself) so it can operate on multiple levels all the same.

Changing array keys is actually not really possible, there is not function like array_rename_key or such. Instead, the item with the new key is added and then the item with the old key is removed. To not duplicate values, a reference/alias is used for this in the example above:

$a["$k|$p"] = &$v;            
unset($a[$k]);

$a is the array, $v is the value of the current element, $k the key and $p the parent's key.

As new elements are added at the end of the array, inside the foreach a check is needed to quit if a key has been already processed (it's a new key, all new keys are strings).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文