操纵多维PHP数组

时间:2014-08-14 11:51:19

标签: php arrays object multidimensional-array

我正在使用多维PHP数组来跟踪对象,如下所示:

Array(
    ["name1"] => Array(
        ["data"] => Array(
           ["children"] => Array(
               ["name2"] => Array(
                   ["data"] => Array(
                       ["otherData"] => 2
                   )
               ),
               ["name3"] => Array(
                   ["data"] => Array()
               )
           )
        )
    ),
    ["name4"] => Array(
        ["data"] => Array(
            ["someRandomValue"] => "hi"
        )
    )
)

这可以是任意数量的级别,所以我会

需要一个递归函数来添加一个新对象。

我想做这样的事情:

function addToArray($item, $array) {
    if ($item-getData('insertBefore')) {
        //...
    }
    if ($item-getData('insertAfter')) {
        //...
    }
    if ($item-getData('parent')) {
        //...
    }
    foreach($array as &$arraySlice) {
        //..magic here
    }
}

基本上该功能会尝试遵循3个数据选项 尽可能parentinsertBeforeinsertAfter。 如果与之前和之前的信息有冲突之后会出错 并且缺少父母(以及之前/之后)信息只是追加为 最后一个索引,在“name4”之后。

这是一个名为name5

的新项目

parent设置为name1

设置为insertBefore

name3插入如下:

Array(
    ["name1"] => Array(
        ["data"] => Array(
           ["children"] => Array(
               ["name2"] => Array(
                   ["data"] => Array(
                       ["otherData"] => 2
                   )
               ),
               ["name5"] => Array(
                   ["data"] => Array(
                       ["parent"] => "name1",
                       ["insertBefore"] => "name3"
                   )
               ),
               ["name3"] => Array(
                   ["data"] => Array()
               )
           )
        )
    ),
    ["name4"] => Array(
        ["data"] => Array(
            ["someRandomValue"] => "hi"
        )
    )
)

有什么建议吗?在我的尝试中,我似乎无法做到正确。删除任何“nameX”条目的另一个功能也很棒。


编辑:这是我最近的尝试,在我感到困惑之后应该放弃

function addToArray($item, $array) {
    $parent = isset($item->getData('parent'))   ? $item->getData('parent')   : null;
    $before = isset($item->getData('insertBefore')) ? $item->getData('insertBefore') : null;
    $after  = isset($item->getData('insertAfter'))  ? $item->getData('insertAfter')  : null;

    $parentFound = null;
    $prevPart    = null;

    // use & in the loop to work with a reference
    foreach($layout as $key => &$part) {
        if ($key == $parent) {
            $parentFound = 1;
        }

        if ($parentFound || !$parent) {
            if ($after) {
                //..
            }
            if ($before) {
                //..
            }
            //eh, erhm..
        } else if ($part['data']['children']) {
            if (addToArray($item, $part)) {
                return true;
            }
        }
        $prevPart = $part;
    }
    return false;
}

1 个答案:

答案 0 :(得分:0)

如果没有设置大量的代码来测试,很难帮助你解决这个问题,所以我会给你一个强大的评论基础。

function my_recc_func ($parent, $before, $after, $array, $my_data) {

  // Lets search the name in the keys of my current node (root or children)
  foreach ($array as $key => $value) {
    if ($key == $parent) {
      // Found it, so I'll do something here, and return true anyway
      $pos = 0;
      // Now looking for after or before names, and finding the correct pos at which I want to add my_data
      foreach ($value[$data][$children] as $name => $arr) {
        ++$pos;
        if ($name == $after) {
          break;
        }
        if ($name == $before) {
          --$pos;
          break;
        }
      }
      // Using the array_slice trick to insert my_data where I want inside of the array
      // It is now my new children with data inserted
      $new_children = array_slice ($value[$data][$children], 0, $pos, true) + $my_data + array_slice, $pos, count($value[$data][$children]), true);
      // $value[$data][$children] becomes $new_children
      // Code it as you want, if you need references or not or with a temporary array
      return true;
    } else {
      // That name isn't the correct one, so I'll see in the children of that node
      if (my_recc_func($parent, $before, $after, $value[$data][$children])) {
        return true;
      }
      // If I didn't find it in the children nodes, I'll keep going with the following nodes of the current parent
    }
  }
  // Didn't find anything in the children or in the current node, bye
  return false;

}

您可能需要应用一些更改才能使其工作(正如您所说的使用引用,或检查之前和之后的不一致),但主要逻辑在这里。

希望它可以帮助你获得有效的东西。

编辑:好的,看看你的最后一次尝试,看起来你已经有了非常相似的东西。如果你告诉我你的代码有什么问题,我会帮助你让它运作