组合多个阵列

时间:2016-04-20 15:02:14

标签: php arrays multidimensional-array

我有这样的数组 数组1:

Array
(
[0] => Array
    (
        [0] => 0
        [1] => -0.025
    )

[1] => Array
    (
        [0] => 0
        [1] => -0.025
    )

[2] => Array
    (
        [0] => 0
        [1] => -0.025
    )
)

数组2:

Array
(
[0] => Array
    (
        [0] => 0
        [1] => -0.025
    )

[1] => Array
    (
        [0] => 0
        [1] => -0.025
    )
)

数组3:

Array
(
[0] => Array
    (
        [0] => 0
        [1] => -0.025
    )

[1] => Array
    (
        [0] => 0
        [1] => -0.025
    )

[2] => Array
    (
        [0] => 0
        [1] => -0.025
    )

[3] => Array
    (
        [0] => 0
        [1] => -0.025
    )
)

以及更多。 我想将它们组合到这个

Array
(
[0] => Array
    (
        [0] => 0
        [1] => -0.025
        [2] => 0
        [3] => -0.025
        [4] => 0
        [5] => -0.025
    )

[1] => Array
    (
        [0] => 0
        [1] => -0.025
        [2] => 0
        [3] => -0.025
        [4] => 0
        [5] => -0.025
    )

[2] => Array
    (
        [0] => 0
        [1] => -0.025
        [2] => 0
        [3] => 0
        [4] => 0
        [5] => -0.025
    )

[3] => Array
    (
        [0] => 0
        [1] => 0
        [2] => 0 // These (0-3) are 0 because the other two arrays haven't 3 in the first level
        [3] => 0
        [4] => 0
        [5] => -0.025
    )
)

数组在第一级中具有不同数量的条目。在第二级,总有2个条目。 在组合数组的第二级中,前两个键(0和1)应始终具有来自第一个数组的条目。后两个键(2和3)应始终具有第二个数组中的条目,依此类推。在我的例子中,我想要组合30个数组。 如果数组的第一级条目数多于其他条目,则所有条目的值应为0。

我希望你理解这一点:)

1 个答案:

答案 0 :(得分:1)

我建造了它; - /

Working demonstration at eval.in

要求:

基本上它是将行转换为列。

  • 输出列都具有最长数组的长度。
  • 源阵列可以具有不同的长度。假设任何空条目的值为array(0, 0)
  • 输出列转换为单维数组。即源值数组附加到列数组。

说明:

我决定使用所有数组都有的内部迭代器。即阵列已经可以记录它们所在的状态,例如它们所在的当前位置(行)。

之后就是“家务管理”:

  • 保留一个列表,列出哪些数组仍有待处理的条目。如果没有,那么我们就完成了。
  • 记录我们正在创建的输出列($ mergedEntryNo)。

  • 扫描当前行的每个(行)读取条目。

  • 每行之后
  • :前进到下一行并记录哪些数组处于活动状态 - 如果有的话。

完成工作的类(SimpleMerge)

class SimpleMerge {

    protected $sources = array();     // a list of arrays!
    protected $sourceCount = 0;       // useful

    protected $isActive = array();    // which of them have entries to process.

    public    $merged = array();      // output in here and public

    protected $anyActiveSources = false;

    // need a list of arrays    
    public function __construct(array $allSources)
    {
        $this->sources = $allSources;
        $this->sourceCount = count($allSources);
        $this->isActive = array_fill(0, $this->sourceCount, true);
    }

    // generate the output by scanning the arrays line by line
    public function generateOutput()
    {
        $this->generateInit();

        $mergedEntryNo = 0;
        while ($this->anyActiveSources) {

            // set the next output entries   
            for ($sourceNo = 0; $sourceNo < $this->sourceCount; $sourceNo++) {
                $this->addEntry($mergedEntryNo, $this->getEntry($sourceNo));
            }        

            $mergedEntryNo++;
            $this->nextPassAdvance();  
            $this->setIsActiveSource();
        }

        return $this->merged;
    }


    // ensure everything is initialized correctly
    public function generateInit()
    {        
        $this->merged = array();

        foreach ($this->sources as &$source) { 
            reset($source); // force internal iterators to the start

            $this->merged[] = array(); // empty arrays in the output
        } 
        unset($source);

        $this->setIsActiveSource();
    }    

    // add to output
    public function addEntry($mergedNo, array $values)
    {
        foreach ($values as $value) {
            $this->merged[$mergedNo][] = $value;
        }
    }

    // get the current source entry - will be array of zeroes if end of array
    public function getEntry($sourceNo)
    {
        if ($this->isActive[$sourceNo]) {
            return current($this->sources[$sourceNo]);
        }
        else {
            return array(0, 0);
        }
    } 

    // check and set which ones are still active and also indicate if any are active
    public function setIsActiveSource()
    {
        $activeCount = 0;
        for ($sourceNo = 0; $sourceNo < $this->sourceCount; $sourceNo++) {

            $isActive = current($this->sources[$sourceNo]) !== false;
            $this->isActive[$sourceNo] = $isActive;
            $activeCount = $activeCount + ($isActive ? 1 : 0);
        }
        $this->anyActiveSources = $activeCount > 0;
    }

    // advance iterators on the sources that are still active
    public function nextPassAdvance()
    {
        for ($sourceNo = 0; $sourceNo < $this->sourceCount; $sourceNo++) {

            if ($this->isActive[$sourceNo]) { // was last time
                next($this->sources[$sourceNo]); 
            }
        }        
    }    
}

运行它

// create and run the generator...

$mergeAll = new SimpleMerge($allSourcesList);
$merged = $mergeAll->generateOutput();

输出:

注意,输入中没有零值。值表示源表和条目号。

Outpt: Array
(
    [0] => Array
        (
            [0] => 11
            [1] => -11.025
            [2] => 21
            [3] => -21.025
            [4] => 31
            [5] => -31.025
            [6] => 41
            [7] => -41.025
        )

    [1] => Array
        (
            [0] => 12
            [1] => -12.025
            [2] => 22
            [3] => -22.025
            [4] => 32
            [5] => -32.025
            [6] => 42
            [7] => -42.025
        )

    [2] => Array
        (
            [0] => 13
            [1] => -13.025
            [2] => 0
            [3] => 0
            [4] => 33
            [5] => -33.025
            [6] => 43
            [7] => -43.025
        )

    [3] => Array
        (
            [0] => 0
            [1] => 0
            [2] => 0
            [3] => 0
            [4] => 34
            [5] => -34.025
            [6] => 44
            [7] => -44.025
        )
)