PHP - 基于索引位置递增数组

发布于 2024-10-17 10:16:30 字数 3022 浏览 1 评论 0原文

我有一个脚本可以处理另一个页面上父/子元素的命名。名称的格式类似于 E5-2-3,它表示第五个元素的第二个子元素的第三个子元素。

我需要做的是将父名称传递给函数并返回下一个子名称。该值将是最后一个子级的增量,如果是第一个子级,则为 1。

(我希望这对某人有意义)

索引数组看起来像这样:

1=>null
2=>null
3=>
    1=>null
    2=>null
    3=>
        1=>null
4=>null
5=>
    1=>null
    2=>
        1=>null
        2=>null
        3=>null //the element I was talking about above
6=>
    1=>null
7=>null

到目前为止我的代码是

    $projectNumber = $_GET['project_number'];
    @$parentNumber = $_GET['parent_number']; //suppressed as it may not be set

    $query = mysql_query("SELECT e_numbers FROM project_management WHERE project_number = '$projectNumber'");
    $resultArray = mysql_fetch_assoc($query);
    $eNumbers = unserialize($resultArray['e_numbers']);

    if (!is_array($eNumbers)&&!isset($parentNumber)){ //first e_number assigned
        $eNumbers[1] = null; //cant possibly have children so null for now
        $nextENumber =  'E1';
    }else{
        if (!isset($parentNumber)){
            $nextNumber = count($eNumbers)+1;
            $eNumbers[$nextNumber] = null; //cant possibly have children so null for now
            $nextENumber = 'E'.$nextNumber;
        }else{
            $parentIndex = explode('-', str_replace('E', '', $parentNumber));
            //$nextENumber = //assign $nextENumber the incremented e number
        }
    }

    echo $nextENumber;

            //(then goes on to update sql etc etc)

这一切都很好,但对于我需要获取/分配深度数字的行。我认为这应该是某种基于 $parentIndex$eNumbers 数组的递归函数,但是当涉及到递归时,我有点超出了我的深度。

任何指向正确方向的指针都会有很大的帮助。

PS 如果有更好的方法来处理不断增加的父母/孩子关系,我会洗耳恭听。我唯一无法控制的是传入/传出的数字的格式(必须是EX-YZ-...

更新我能够开发@ircmaxell 的功能在我的上下文中运行得更好。该函数要求您传入一个从零开始的数组(可以为空)和一个可选路径。它返回新路径并更新索引数组以包含新路径。如果未找到索引,则返回错误消息。

function getNextPath(&$array, $path) { //thanks to  ircmaxell @ stackoverflow for the basis of this function
            $newPath = '';
            $tmp =& $array;
            if (is_string($path)) {
                $path = explode('-', str_replace('E', '', $path));
                $max = count($path);            
                foreach ($path as $key => $subpath) {
                    if (is_array($tmp)) {
                        if (array_key_exists($subpath, $tmp)){
                            $tmp =& $tmp[$subpath];
                                $newPath[] = $subpath;
                        }else{
                            return "Parent Path Not Found";
                        }

                    }
                }
            }           
            $tmp[] = null;
            $newPath[] = count($tmp)-1;
            if (count($newPath)>1){
                $newPath = implode('-', $newPath);
            }else{
                $newPath = $newPath[0];
            }           
            return "E".$newPath;
        }

I have a script which handles the naming of parent/child elements on another page. The format for the name is like E5-2-3 which represents the third child of the second child of the fifth element.

What I need to do is pass in the parent name to the function and return the name for the next child. This value would be the increment of the last child or 1 if it is the first child.

(I hope this makes some sense to someone)

The index array looks something like this:

1=>null
2=>null
3=>
    1=>null
    2=>null
    3=>
        1=>null
4=>null
5=>
    1=>null
    2=>
        1=>null
        2=>null
        3=>null //the element I was talking about above
6=>
    1=>null
7=>null

My Code so far is

    $projectNumber = $_GET['project_number'];
    @$parentNumber = $_GET['parent_number']; //suppressed as it may not be set

    $query = mysql_query("SELECT e_numbers FROM project_management WHERE project_number = '$projectNumber'");
    $resultArray = mysql_fetch_assoc($query);
    $eNumbers = unserialize($resultArray['e_numbers']);

    if (!is_array($eNumbers)&&!isset($parentNumber)){ //first e_number assigned
        $eNumbers[1] = null; //cant possibly have children so null for now
        $nextENumber =  'E1';
    }else{
        if (!isset($parentNumber)){
            $nextNumber = count($eNumbers)+1;
            $eNumbers[$nextNumber] = null; //cant possibly have children so null for now
            $nextENumber = 'E'.$nextNumber;
        }else{
            $parentIndex = explode('-', str_replace('E', '', $parentNumber));
            //$nextENumber = //assign $nextENumber the incremented e number
        }
    }

    echo $nextENumber;

            //(then goes on to update sql etc etc)

This is all fine but for the line where I need to get/assign deep numbers. I think this should be some kind of recursive function based on the $parentIndex and $eNumbers arrays, however I'm a bit out of my depth when it comes to recursion.

Any pointer in the right direction will be a great help.

PS
If there is a better way to handle incrementing parent/child relationships I'm all ears. The only thing out of my control is the format of the numbers being passed in/out (Has to be EX-Y-Z-...)

UPDATE I was able to develop @ircmaxell 's function to function more better in my context. The function required you to pass in a zero based array(can be empty) and an optional path. It returns the new path and updates the index array to include the new path. An error message is returned if the index is not found.

function getNextPath(&$array, $path) { //thanks to  ircmaxell @ stackoverflow for the basis of this function
            $newPath = '';
            $tmp =& $array;
            if (is_string($path)) {
                $path = explode('-', str_replace('E', '', $path));
                $max = count($path);            
                foreach ($path as $key => $subpath) {
                    if (is_array($tmp)) {
                        if (array_key_exists($subpath, $tmp)){
                            $tmp =& $tmp[$subpath];
                                $newPath[] = $subpath;
                        }else{
                            return "Parent Path Not Found";
                        }

                    }
                }
            }           
            $tmp[] = null;
            $newPath[] = count($tmp)-1;
            if (count($newPath)>1){
                $newPath = implode('-', $newPath);
            }else{
                $newPath = $newPath[0];
            }           
            return "E".$newPath;
        }

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

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

发布评论

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

评论(1

流年里的时光 2024-10-24 10:16:30

这是一种方法:

function incrementPath(&$array, $path) {
    if (is_string($path)) {
        $path = explode('-', str_replace('E', '', $path);
    }
    $tmp =& $array;
    foreach ($path as $subpath) {
        if (is_array($tmp) && isset($tmp[$subpath])) {
            $tmp =& $tmp[$subpath];
        } else {
            return false; // Could not find entire path
        }
    }
    $tmp++;
    return true;
}

现在,如果您希望它动态创建路径,只需将 return false; 更改为:

$tmp[$subpath] = array();
$tmp =& $tmp[$subpath];

然后在循环后添加一个检查,看看它是否不是整数,并显式设置为0 如果不是...

编辑: 啊哈,现在我明白了:

function getNextPath(&$array, $path) {
    if (is_string($path)) {
        $path = explode('-', str_replace('E', '', $path);
    }
    $newPath = '';
    $tmp =& $array;
    $max = count($path) - 1;
    foreach ($path as $key => $subpath) {
        if (is_array($tmp) && isset($tmp[$subpath])) {
            $tmp =& $tmp[$subpath];
            if ($key < $max) {
                $newPath .= '-'.$subpath;
            }
        } else {
            return 'E' . ltrim($newPath . '-1', '-'); // Could not find entire path
        }
    }
    if (is_array($tmp)) {
        return 'E' . ltrim($newPath . '-' . count($tmp), '-');
    } else {
        //it's a value, so make it an array
        $tmp = array();
        return 'E' . ltrim($newPath . '-' . 1, '-');
    }
}

我认为这应该做你想要的(它返回你正在寻找的下一个可用路径)。
}

Here's one way:

function incrementPath(&$array, $path) {
    if (is_string($path)) {
        $path = explode('-', str_replace('E', '', $path);
    }
    $tmp =& $array;
    foreach ($path as $subpath) {
        if (is_array($tmp) && isset($tmp[$subpath])) {
            $tmp =& $tmp[$subpath];
        } else {
            return false; // Could not find entire path
        }
    }
    $tmp++;
    return true;
}

Now, if you want it to dynamically create paths, just change the return false; to:

$tmp[$subpath] = array();
$tmp =& $tmp[$subpath];

And then add a check after the loop to see if it's not an integer, and explicitly set to 0 if it isn't...

Edit: AHHH, now I understand:

function getNextPath(&$array, $path) {
    if (is_string($path)) {
        $path = explode('-', str_replace('E', '', $path);
    }
    $newPath = '';
    $tmp =& $array;
    $max = count($path) - 1;
    foreach ($path as $key => $subpath) {
        if (is_array($tmp) && isset($tmp[$subpath])) {
            $tmp =& $tmp[$subpath];
            if ($key < $max) {
                $newPath .= '-'.$subpath;
            }
        } else {
            return 'E' . ltrim($newPath . '-1', '-'); // Could not find entire path
        }
    }
    if (is_array($tmp)) {
        return 'E' . ltrim($newPath . '-' . count($tmp), '-');
    } else {
        //it's a value, so make it an array
        $tmp = array();
        return 'E' . ltrim($newPath . '-' . 1, '-');
    }
}

I think that should do what you want (it returns the next available path under what you're looking for).
}

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