PHP中有没有类似JavaScript扩展语法用于构建数组的功能?

5

我已经在问题上询问了如何将Ruby函数转换为JS,并且现在我正在尝试使用JS实现到PHP,但是某些地方似乎无法正常工作,请告诉我我缺少了什么?

以下是JS代码:

function transpose(a) {
    return a.length === 0 ? a : a[0].map((col, i) => a.map((row) => row[i]))
}

function f(a) {
    return a.length === 0 ? [] : [...a.shift(), ...f(transpose(a).reverse())];
} 

console.log(f([[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]))

在PHP中可以这样做:
function transpose($array) 
{
    if (count($array) === 0) return $array;

    foreach ($array as  $rowkey => $row)
    {
        foreach($row as $colkey => $col)
        {
            $out[$colkey][$rowkey] = $col;
        }
    }

    return $out;
}

function f($a)
{
    return (count($a) === 0) 
    ? [] 
    : [
        array_shift(...$a), 
        f(array_reverse(transpose(...$a)))
    ];
}

print_r(f([[1,2,3,4],[10,11,12,5],[9,8,7,6]]));

有问题吗?错误信息:

警告:array_shift()函数期望只传入1个参数,但是在[...][...]的第24行传入了3个参数

无效的参数传递给foreach()函数,在[...][...]的第10行

警告:无效的参数传递给foreach()函数,在[...][...]的第10行

警告:无效的参数传递给foreach()函数,在[...][...]的第10行

警告:无效的参数传递给foreach()函数,在[...][...]的第10行

注意:未定义变量$out,在[...][...]的第16行

警告:array_reverse()函数期望传入一个数组作为参数,但是传入了null,在[...][...]的第25行

警告:count()函数的参数必须是一个数组或实现了Countable接口的对象,在[...][...]的第21行


1
请问您能否添加更多关于“某些东西不起作用”的细节说明? - Don't Panic
你不能这样做。因为 PHP 是预编译的,而 JS 是后编译的,在 JS 方面无法执行 PHP。 - Forbs
array_shift(...$a) 应该改为 ...array_shift($a) 才能与JS等效。 - Barmar
@Forbs,所以这是不可能的吗? - muesli
3个回答

4
你不需要在PHP版本中使用...运算符,只需要将移动的行与递归调用的结果合并即可。
function f($a)
{
    return (count($a) === 0) 
    ? [] 
    : array_merge(
        array_shift($a), 
        f(array_reverse(transpose($a)))
    );
}

array_merge(array_shift($a), f(array_reverse(transpose($a))))

这里发生的事情与此相同:
[...a.shift(), ...f(transpose(a).reverse())]

...在JS中展开数组元素。在PHP中它也类似,但这里只适用于函数定义或调用。


3

在PHP中,与JS不同,您的...(也称为“splat”)操作符放置在不同的位置。

此外,在PHP 7.4之前,展开运算符不能用于数组字面量,只能用于函数调用。在f()函数中的使用等同于array_merge()

function f($a)
{
    return (count($a) === 0) 
    ? [] 
    : array_merge(
        array_shift($a), 
        f(array_reverse(transpose($a)))
    );
}

DEMO


Parse error: syntax error, unexpected '...' (T_ELLIPSIS) - muesli
你不能在数组字面量中使用 ...,所以我改成了函数调用。 - Barmar
PHP 7.4 现在支持在数组内部进行解包。https://www.php.net/manual/zh/migration74.new-features.php - Rizky Arlin
谢谢,我已经在问题中添加了关于 7.4 的说明。 - Barmar

1

你的array_shift有太多的参数.. 你只需要$a。同样适用于array_reverse

<?php
function transpose($array)
{
    if (count($array) === 0) return $array;

    foreach ($array as  $rowkey => $row)
    {
        foreach($row as $colkey => $col)
        {
            $out[$colkey][$rowkey] = $col;
        }
    }

    return $out;
}

function f($a)
{
    return (count($a) === 0)
    ? []
    : [
        array_shift($a),
        f(array_reverse(transpose($a)))
    ];
}

print_r(f([[1,2,3,4],[10,11,12,5],[9,8,7,6]]));

结果

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

    [1] => Array
        (
            [0] => Array
                (
                    [0] => 5
                    [1] => 6
                )

            [1] => Array
                (
                    [0] => Array
                        (
                            [0] => 7
                            [1] => 8
                            [2] => 9
                        )

                    [1] => Array
                        (
                            [0] => Array
                                (
                                    [0] => 10
                                )

                            [1] => Array
                                (
                                    [0] => Array
                                        (
                                            [0] => 11
                                            [1] => 12
                                        )

                                    [1] => Array
                                        (
                                        )

                                )

                        )

                )

        )

)

1
这个结果与 JavaScript 版本不一样。 - Barmar
1
它应该返回一个扁平的数组,而不是嵌套层次很深的数组。 - Barmar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接