0

Basically, I want to convert the below multidimensional array:

Array
(

[0] => Array
    (
        [0] => foo
        [1] => bar
        [2] => hello
    )

[1] => Array
    (
        [0] => world
        [1] => love
    )

[2] => Array
    (
        [0] => stack
        [1] => overflow
        [2] => yep
        [3] => man
    )
)

Into this:

Array
(
  [0] => foo
  [1] => world
  [2] => stack
  [3] => bar
  [4] => love
  [5] => overflow
  [6] => hello
  [7] => yep
  [8] => man
)
  1. first element from first sub-array
  2. first element from second sub-array, etc
  3. second element from first sub-array
  4. second element from second sub-array, etc...
2
  • Is the order important? Commented May 20, 2016 at 22:51
  • yes @Sven ! the order is very important. Commented May 20, 2016 at 22:52

2 Answers 2

1

So I've had a couple beers and I'll try and tighten this up later, but this does the trick for integer indexed arrays:

$result = array();

for($i=0; $c=array_column($array, $i); $i++) {
    $result = array_merge($result, $c);
}
print_r($result);
  • Loop getting an array of columns starting with column 0 and increment the column number.
  • So long as there are columns, get an array of that column and merge with the result.
Sign up to request clarification or add additional context in comments.

1 Comment

I do like the use of array_column() here.
0

There is an often overlooked Iterator that will help you here: The MultipleIterator.

I have created some demo code: https://3v4l.org/beOMV

<?php

$arr = [
    0 => [
        0 => 'foo',
        1 => 'bar',
        2 => 'hello',
    ],
    1 => [
        0 => 'world',
        1 => 'love',
    ],
    2 => [
        0 => 'stack',
        1 => 'overflow',
        2 => 'yep',
        3 => 'man',
    ]
];

$parallelIterator = new MultipleIterator(MultipleIterator::MIT_NEED_ANY|MultipleIterator::MIT_KEYS_NUMERIC);

$parallelIterator->attachIterator(new ArrayIterator($arr[0]));
$parallelIterator->attachIterator(new ArrayIterator($arr[1]));
$parallelIterator->attachIterator(new ArrayIterator($arr[2]));

$result = [];

foreach ($parallelIterator as $values) {
    foreach ($values as $value) {
        if ($value !== null) {
            $result[] = $value;
        }
    }    
}

var_dump($result);

Essentially, iterating over the MultipleIterator will give you an array with all the first entries (and then second and so on) of ALL attached iterators in parallel. By using either MultipleIterator::MIT_NEED_ANY or MultipleIterator::MIT_NEED_ALL you can decide that the loop should stop either when the last iterator has no more elements, or when the first iterator runs out of elements. When you run until the last element of the last iterator, you'll get NULL instead.

When attaching iterators, you can also add a key that will be used in the array when iterating, and have to uses MultipleIterator::MIT_KEYS_ASSOC - I have simply used numeric indices here because the source of the particular array was not interesting.

The result is

array(9) { 
    [0]=> string(3) "foo" 
    [1]=> string(5) "world" 
    [2]=> string(5) "stack" 
    [3]=> string(3) "bar" 
    [4]=> string(4) "love" 
    [5]=> string(8) "overflow" 
    [6]=> string(5) "hello" 
    [7]=> string(3) "yep" 
    [8]=> string(3) "man" 
}

Yes, you can iterate over that initial array when attaching the sub arrays to the MultipleIterator if you want:

foreach ($arr as $innerArr) {
    $parallelIterator->attachIterator(new ArrayIterator($innerArr));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.