0

Here is my code:

$arr = [
    0 => [1, 2, 3, 4],
    1 => ['one', 'two', 'three', 'four'] 
    ];

$res = [];    
foreach ($arr as $item){
    foreach($item as $i){
        $res = [$i, $item];
    }
}

print_r($res);

/*
Array
(
    [0] => four
    [1] => Array
        (
            [0] => one
            [1] => two
            [2] => three
            [3] => four
        )

)

As you see the result doesn't make any sense. Here is expected result:

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => one
        )
    [1] => Array
        (
            [0] => 2
            [1] => two
        )
    [2] => Array
        (
            [0] => 3
            [1] => three
        )
    [3] => Array
        (
            [0] => 4
            [1] => four
        )
)

You know, nested loops always make me confuse. Anyway, does anybody know how can I achieve to the expected result?

Martin AJ
  • 6,261
  • 8
  • 53
  • 111

5 Answers5

8

Update:

Or, as noted below by Shafizadeh, simply:

<?php
$arr = [
    [1, 2, 3, 4],
    ['one', 'two', 'three', 'four']
];

$out = array_map(null, ...$arr);

This?

<?php
$arr = [
    [1, 2, 3, 4],
    ['one', 'two', 'three', 'four']
];

// array_map accepts an open number of input arrays and applies
// a given callback on each *set* of *i-th* values from these arrays.
// The return value of the callback will be the new array value
// of the final array:
                            // get all function arguments as an array
$out = array_map(function (...$r) {
    return $r;
}, ...$arr); // *spread* input array as individual input arguments

print_r($out);

// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => one
//         )
// 
//     [1] => Array
//         (
//             [0] => 2
//             [1] => two
//         )
// ...

Demo: https://3v4l.org/uJNKG

Ref: http://php.net/manual/functions.arguments.php#functions.variable-arg-list.new

Yoshi
  • 54,081
  • 14
  • 89
  • 103
  • OMG .. what is `...` in the behind of `$arr` ??? I've never seen such syntax before. – Martin AJ Jun 12 '17 at 07:30
  • 2
    [*PHP RFC: Argument Unpacking*](https://wiki.php.net/rfc/argument_unpacking) – Yoshi Jun 12 '17 at 07:31
  • 1
    @MartinAJ that's variadic syntax. http://php.net/manual/en/functions.arguments.php – Nathan F. Jun 12 '17 at 07:31
  • @Yoshi I cannot use these syntex in array_walk, where can the ...$arr used? Thank you. – LF00 Jun 12 '17 at 08:02
  • @KrisRoofe What would you want to do with `array_walk`? – Yoshi Jun 12 '17 at 09:39
  • `array_walk( ...$arr, function (...$r) { print_r( $r); });` – LF00 Jun 12 '17 at 09:55
  • @KrisRoofe That won't work, because `array_walk` has a different function signature. But why use `array_walk`? – Yoshi Jun 12 '17 at 09:58
  • @Yoshi It's the first time to see the code in your answer. And I've not understand why the `$r` is assigned. And `array_walk` and` array_map` both can traverse an array, so I just try to use it in `array_walk`. – LF00 Jun 12 '17 at 10:04
  • 1
    @KrisRoofe I understand. You can think of the `...` operator as simple syntactic sugar. Meaning it relieves you of writing loops in specific places (calling a function/method, using function/method arguments). So in my answer, I combine this usage and the built-in `array_map` function. It just so happens that both work well together. – Yoshi Jun 12 '17 at 10:07
  • It's basically fancy looking [`func_get_args()`](https://secure.php.net/manual/function.func-get-args.php) and [`call_user_func_array`](https://secure.php.net/manual/function.call-user-func-array.php). – Yoshi Jun 12 '17 at 10:14
  • 1
    Or simply [`array_map(null, ...$arr);`](https://3v4l.org/2pIDY) – Shafizadeh Jul 03 '17 at 07:33
  • 1
    @Shafizadeh Nice one! As long as this question stays closed, I think you can't add this as an answer. I'll keep it in mine for the time being then. – Yoshi Jul 03 '17 at 07:50
1

Try to imagine what you would do if you would do this by hand:

  • First step: Take a value from array A and a value from array B at a cretain position (Let's call it $i).
  • Second step: Add those two values to a new array C.
  • Third step: Increase $i by one
  • Fourth Step: repeat this until you have looped through the whole array.
Tobias F.
  • 1,050
  • 1
  • 11
  • 23
1

You can use array_column() for that purpose with a single for loop.

$arr = [
    0 => [1, 2, 3, 4],
    1 => ['one', 'two', 'three', 'four'] 
    ];

$res = [];    
foreach ($arr[0] as $key => $val){
     $res[] = array_column($arr, $key);
}

Here's working example: https://3v4l.org/vXdvD

Jakub Matczak
  • 15,341
  • 5
  • 46
  • 64
1

Iterate over the first sub-array using the $key => $value syntax of foreach, combining the element at the iteration index (i.e. $item) with the corresponding element from the second sub-array (i.e. $arr[1][$key]):

foreach ($arr[0] as $key => $item) {
    $res[] = [$item, $arr[1][$key] ];
}

See an demonstration here

Update

I admit I learned from Yoshi's answer about the spread operator - I knew it existed in JavaScript but not PHP. The explanation below starts applying array_map() without the spread operator and then applies it.

To start applying array_map() the first parameter is the anonymous function, which returns the two arguments it accepts in a single array. The second and third parameters are the two sub-arrays.

$arr = [
    0 => [1, 2, 3, 4],
    1 => ['one', 'two', 'three', 'four'] 
    ];

$res = array_map(function($item0, $item1) {
    return [ $item0, $item1];
}, $arr[0], $arr[1]);

print_r($res);

See the demonstration here.

Then taking that code, the spread operator can be used to substitute for the arguments of the anonymous function (i.e. $item0, $item1) as well as the second and third arguments to array_map() (i.e. $arr[0], $arr[1])

$res = array_map(function(...$items) {
    return $items;
}, ...$arr);

See the demonstration for that here.

Community
  • 1
  • 1
Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
0
$arr = [
  0 => [1, 2, 3, 4],
  1 => ['one', 'two', 'three', 'four']
];
$res = [];
foreach ($arr[0] as $key => $item) {
  $res[] = [$item, $arr[1][$key] ];
}
print_r($res);
  • 2
    Please try to avoid just dumping code as an answer and try to explain what it does and why. Your code might not be obvious for people who do not have the relevant coding experience. Please edit your answer to include [clarification, context and try to mention any limitations, assumptions or simplifications in your answer.](https://stackoverflow.com/help/how-to-answer) – Frits Jun 12 '17 at 08:31