重新排序,加入和删除数组php的元素

时间:2019-03-10 04:27:05

标签: php

所以我有一个看起来像这样的数组(更容易看到原始输出)


0  | from:2  page   | to:1  split
1  | from:1  split  | to:3  page
2  | from:1  split  | to:4  page
3  | from:1  split  | to:5  page
4  | from:3  page   | to:0  join
5  | from:4  page   | to:0  join
6  | from:5  page   | to:0  join
7  | from:8  page   | to:0  join
8  | from:0  join   | to:12 page
9  | from:1  split  | to:8  page
10 | from:12 page   | to:10 end
11 | from:   start  | to:2  page

我想做的是通过某种方式解析它并提出以下内容:

0 | start
1 | page
2 | split 3, 4, 5, 8
3 | page
4 | end

所以从本质上讲,我试图将其组织成一个最终的数组,该数组遵循从头到尾的路径。

参与规则:

在有拆分的地方:将“ to page”组合到一个子数组中,在有“ join”的地方,删除引用。并在其中有一个“从连接到页面”的地方,只需创建页面即可。因此最终输出应如下所示:

array(
    'start',
    'page',
    'split' => array (
      3, 4, 5, 8
    ),
    'page',
    'end'
)

更新:

这是我正在使用的原始格式

Array
(
    [operators] => Array
        (
            [0] => Array
                (
                    [type] => join
                )

            [1] => Array
                (
                    [type] => split
                )

            [2] => Array
                (
                    [type] => page
                )

            [3] => Array
                (
                    [type] => page
                )

            [4] => Array
                (
                    [type] => page
                )

            [5] => Array
                (
                    [type] => page
                )

            [8] => Array
                (
                    [type] => page
                )

            [9] => Array
                (
                    [type] => start
                )

            [10] => Array
                (
                    [type] => end
                )

            [12] => Array
                (
                    [type] => page

                )

        )

    [links] => Array
        (
            [0] => Array
                (
                    [fromOperator] => 2
                    [toOperator] => 1
                )

            [1] => Array
                (
                    [fromOperator] => 1
                    [toOperator] => 3

                )

            [2] => Array
                (
                    [fromOperator] => 1
                    [toOperator] => 4
                )

            [3] => Array
                (
                    [fromOperator] => 1
                    [toOperator] => 5
                )

            [4] => Array
                (
                    [fromOperator] => 3
                    [toOperator] => 0
                )

            [5] => Array
                (
                    [fromOperator] => 4
                    [toOperator] => 0
                )

            [6] => Array
                (
                    [fromOperator] => 5 
                    [toOperator] => 0
                )

            [7] => Array
                (
                    [fromOperator] => 8
                    [toOperator] => 0
                )

            [8] => Array
                (
                    [fromOperator] => 0
                    [toOperator] => 12
                )

            [9] => Array
                (
                    [fromOperator] => 1  
                    [toOperator] => 8

                )

            [10] => Array
                (
                    [fromOperator] => 12
                    [toOperator] => 10
                )

            [11] => Array
                (
                    [fromOperator] => 9
                    [toOperator] => 2

                )

        )

)

``

1 个答案:

答案 0 :(得分:2)

Boo Yahh !!

我不得不小睡一下,但是现在我确定那4个。

<?php
$array = array (
    'operators' => 
    array (
        0 => 
        array (
            'type' => 'join'
        ),
        1 => 
        array (
            'type' => 'split'
        ),
        2 => 
        array (
            'type' => 'page'
        ),
        3 => 
        array (
            'type' => 'page'
        ),
        4 => 
        array (
            'type' => 'page'
        ),
        5 => 
        array (
            'type' => 'page'
        ),
        8 => 
        array (
            'type' => 'page'
        ),
        9 => 
        array (
            'type' => 'start'
        ),
        10 => 
        array (
            'type' => 'end'
        ),
        12 => 
        array (
            'type' => 'page'
        ),
    ),
    'links' => 
    array (
        0 => 
        array (
            'fromOperator' => 2,
            'toOperator' => 1
        ),
        1 => 
        array (
            'fromOperator' => 1,
            'toOperator' => 3
        ),
        2 => 
        array (
            'fromOperator' => 1,
            'toOperator' => 4
        ),
        3 => 
        array (
            'fromOperator' => 1,
            'toOperator' => 5
        ),
        4 => 
        array (
            'fromOperator' => 3,
            'toOperator' => 0
        ),
        5 => 
        array (
            'fromOperator' => 4,
            'toOperator' => 0
        ),
        6 => 
        array (
            'fromOperator' => 5,
            'toOperator' => 0
        ),
        7 => 
        array (
            'fromOperator' => 8,
            'toOperator' => 0
        ),
        8 => 
        array (
            'fromOperator' => 0,
            'toOperator' => 12
        ),
        9 => 
        array (
            'fromOperator' => 1,
            'toOperator' => 8
        ),
        10 => 
        array (
            'fromOperator' => 12,
            'toOperator' => 10
        ),
        11 => 
        array (
            'fromOperator' => 9,
            'toOperator' => 2
        )
    )
);

代码:

//Flatten to simplify  [$op_id => $array['operators'][n]['type']]
//array_combine and array_keys, just makes sure the keys match
//the original array, because we are missing a few keys (7,8 and 11)
//we have to do this or we lose those references.
$arr_op = array_combine(array_keys($array['operators']), array_column($array['operators'], 'type'));
//print_r($arr_op);

//get our instruction list - combine data to simplify.
//this saves us a bit of work doing the lookup and managing multiple arrays
$instructions = [];
foreach($array['links'] as $link){
    $instructions[]  = [
        'fromOperator'  => $link['fromOperator'],
        'fromOp'        => $arr_op[$link['fromOperator']], // we need them keys to match here
        'toOperator'    => $link['toOperator'],
        'toOp'          => $arr_op[$link['toOperator']] //and here
    ];
} 
//print_r($instructions);

$opp_id = array_search('start',$arr_op); //9 start
//print_r($opp_id);

$i=0;
$output = [];

//loop as long as we have some instructions to process
while(count($instructions)){
    //get the current key of the array
    $key = key($instructions);

    //is this our instruction?
    //we are forced to {potentially} loop the whole array to find it
    //we cannot use array search (even after flattening it out) because of the duplicates
    if($instructions[$key]['fromOperator'] == $opp_id){
        //get and remove the instruction - array reduction
        $instruction = array_splice($instructions, $key, 1)[0];
        //print_r($instruction);
        //print_r($instructions);

        //just for sanity checks.
        echo "{$i}  | from:{$instruction['fromOp']}  {$instruction['toOperator']}  | to:{$instruction['fromOperator']}  {$instruction['toOp']}\n";

        //if the last operation is end, use it as there is no fromOp = end
        $opperation = 'end' == $instruction['toOp'] ? 'end' : $instruction['fromOp'];

        //process instruction
        switch($opperation){
            case 'join': 
                //skip
            break;
            case 'split':  
                //split has to be done as a group
                $output['split']=array_column(array_filter($array['links'],function($ins)use($opp_id){return $ins['fromOperator']==$opp_id;}),'toOperator');

            break;
            default: //start, page, end
                 $output[] = $opperation;
                 //when we find the end, break the switch, break the while
                 if($opperation == 'end') break 2; 
            break;
        }//end switch

        //get the operation key for the next instruction as we consumed it, Yum!
        $opp_id = $instruction['toOperator'];
        ++$i;
    }//end if

    //move the array pointer forward, or reset on false (start over when we hit the end of the array)
    if(false === next($instructions)) reset($instructions);
}//end while

echo "\n";
print_r($output);

输出

0  | from:start  2  | to:9  page
1  | from:page  1  | to:2  split
2  | from:split  4  | to:1  page
//Some "magic" happens here and we warp to 0
3  | from:page  0  | to:4  join
4  | from:join  12  | to:0  page
5  | from:page  10  | to:12  end

Array
(
    [0] => start
    [1] => page
    [split] => Array
    (
         [0] => 3
         [1] => 4
         [2] => 5
         [3] => 8
    )
    [2] => page
    [3] => end
)

Sandbox

限制

由于PHP数组键是唯一的,因此您必须将所有“拆分”操作分组为一个。对于当前的输入数组结构,即使没有“使用split作为键”,也没有“真正”的解决方法。 (希望这可以解决问题)

//The #{n} in the first column, is the (apx) order this thing runs in.
//#(hashtag) will be used for all numbers with a # (in my explanation below)
//if they don't have a # and are code, assume they are the second column value (in my explanation below)

#2    -   0  | from:2  page   | to:1  split //--> start of split
#3    -   1  | from:1  split  | to:3  page //--> go to 3 
#dup  -   2  | from:1  split  | to:4  page // -> go to 4
#4    -   3  | from:1  split  | to:5  page // -> go to 5
#dup  -   4  | from:3  page   | to:0  join //<-- if you go to 0 -> 12 -> end
#5    -   5  | from:4  page   | to:0  join //<-- if you go to 0 -> 12 -> end
#dup  -   6  | from:5  page   | to:0  join //<-- if you go to 0 -> 12 -> end
#6    -   7  | from:8  page   | to:0  join
#7    -   8  | from:0  join   | to:12 page
#dup  -   9  | from:1  split  | to:8  page //--> go to 8 end of split
#8    -   10 | from:12 page   | to:10 end // {exit}
#1    -   11 | from:   start  | to:2  page

从上面可以看到,#dup个都来自opp:1$array['operators'] = [1 =>['type' => 'split']],但是to:1上只有1个#2和4个{ {1}}个项目。所以我们被迫拆分这些执行,因为您不能同时为1个项目转到4个项目。我们可以循环执行此操作,也可以在我在那里做的这么大的混乱。

例如,以from:1为我们的最后一条好路径:

#3

如您所见,我们无法遵循这些路径,因此我们被迫将它们作为一个整体进行处理。如果我们这样做(遵循路径),我们将只处理#3 - 1 | from:1 split | to:3 page //--> go to 3 ~4 - 4 | from:3 page | to:0 join //<-- if you go to 0 -> 12 -> end ~5 - 8 | from:0 join | to:12 page // way out of wack now. ~6 - 10 | from:12 page | to:10 end {premature termination} #1#2#3~4~5,然后然后程序结束。这就是我先前的回答(基本上)发生的事情,并且我知道这是不正确的。同样,由于重复的~6,我们无法处理其中任何一个,或者很快结束。考虑到数据的结构,我看不出有任何其他解决方法。

我的操作方式(简短)

上面的“技巧”是手动绘制其运行方式。

  1. 利用这些知识,我建立了一个指令列表(以降低复杂性),因此我们在不查找操作名称的情况下处理了一个数组,因此我将该列表称为0(我知道是有创意的)。
  2. 下一个$instructions
    • 是:我们只吃了if($instructions[$key]['fromOperator'] == $opp_id),它删除并返回了数组的一部分。因此,由于我们能够处理这些指令,因此我们的指令清单也在不断减少。
    • 错误:如果数组指针位于末尾,我们将继续执行下一条指令并重置数组。 $instruction = array_splice($instructions, $key, 1)[0];,然后从下一条指令的1开始(在此列表中)。
    • 由于没有真正的排序方法,我们可能不得不在数组上循环几次,所以在处理过程中删除每条指令会更容易做到这一点。
  3. 然后,通过“拆分”和if(false === next($instructions)) reset($instructions);操作进行一些“微调”,以进行切换并收集我们的输出非常简单。
    • “ finagling”只是从主数组中提取所有end的数组,其中toOperator具有与fromOperator相同的键(或{{ 1}}(在这种情况下)
  4. 最后,我们要么用尽了数组项,要么击中了split1循环中的这个if($opperation == 'end') break 2;。谁知道你可以休息一下{这个家伙} ...

我在那儿留下了很多评论,希望这可以解释我是如何做的以及主要问题是什么。

改进

我有这种怪异之处,它只是为“拆分”的所有项目(所有都是动态的)获取所有switch值的平面数组。我至少可以提出5种方法,这就是我选择的方法。

while

您可以遍历每个“拆分”,然后递归地将开关称为“某种程度上”。因为我要删除每条指令,所以第一个“ Split”会从指令列表中拉出,然后才能检查它是否为拆分。这使得使用起来有点困难。但是,您可以执行此操作(如果需要修复该问题):

toOperator

应将其放回指令列表中。 $output['split']=array_column(array_filter($instructions,function($ins)use($opp_id){return $ins['fromOperator']==$opp_id;}),'toOperator'); 的魔力虽然适得其反。然后,您只需要遍历它们,如果它们没有 $instructions = array_splice($instructions, $key, 0, [instructions]); ,则可以遵循它所指向的路径。这可能解决订购方面的某些问题,可能会或可能不会发生。这里的另一个问题是,您将在输出中获得多个array_splice值,因为我只是跳过(双关语意)。因此,如果您尝试对其进行迭代,请记住这一点。我这样做的方式没有必要去解决。但是基本思想是对功能(将部分或全部功能变成一个功能,然后)在拆分发生时对其多次调用。

我没有打扰的另一个问题是,实际上并非所有goto 0项都已从指令列表中删除。在此示例中,这无关紧要,因为我们有page标签。但是,在进行上述改进时,清理起来很容易。

无论如何,我都会把它留给读者练习。

最后一句话

PS:如果您像上面那样编号,那将为我节省大量时间。不过,这是一个有趣的挑战。

希望对您有所帮助,这是由于上述问题而为您提供的数据所能提供的最好的解决方案。可能会有一些次要的性能表现等,但这几乎涵盖了它。

干杯!

* PPS:是的,我知道我的拼写和语法很烂。哦,阅读困难的喜悦。我想一个人不可能在所有方面都擅长。...我花了大约十亿次编辑才能使它更具可读性。