【问题标题】:Move elements using array_chunk with PHP使用 array_chunk 和 PHP 移动元素
【发布时间】:2018-11-23 16:14:43
【问题描述】:

我有一个基本数组,我在其中使用 array_chunk 将其分成 3 个元素。

$array = array(
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'
);

$chunk = array_chunk($array, 3);

结果如下

[
   [
     "a",
     "b",
     "c"
   ],
   [
     "d",
     "e",
     "f"
   ],
   [
     "g",
     "h"
   ]
]

(Las chunk 有 2 个元素)

如果最后一个“块”只有 2 个元素,我怎样才能向下移动第一个块的一个元素,使第一个元素有 2 个?

应该是这样的:

[
   [
     "a",
     "b",
   ],
   [
     "c"
     "d",
     "e",
   ],
   [
     "f"
     "g",
     "h
   ]
]

(第一个块有 2 个元素)

【问题讨论】:

    标签: php arrays chunks


    【解决方案1】:

    最简单的方法是多次执行 erray_reverse:首先反转整个数组,然后拆分,然后反转每个块,最后是块数组。

    作为一个单行,它看起来像这样:$chunk = array_reverse(array_map('array_reverse', array_chunk(array_reverse($array), 3)));

    但请注意,反转数组是一项昂贵的操作,因此如果您的数组实际上比您的示例中的要大,则不推荐使用这种方法。


    更有效但也更多的代码: 使用模数计算第一个块中需要的元素数: $first_chunk_size = count($array) % 3;

    接下来,如果数组大小是块大小的倍数,为了避免空数组,如果模数为 0,则更正块大小: $first_chunk_size = $first_chunk_size == 0 ? 3 : $first_chunk_size;

    然后,剪掉第一部分: $first_chunk = array_slice($array, 0, $first_chunk_size);

    接下来,拆分数组的其余部分: $chunks = array_chunk(array_slice($array,$first_chunk_size),3);

    然后将第一个块和其他块组合成一个数组: array_unshift($chunks, $first_chunk);

    第二种方法的完整代码:

    $array = [
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'
    ];
    
    $first_chunk_size = count($array) % 3;
    $first_chunk_size = $first_chunk_size == 0 ? 3 : $first_chunk_size;
    
    $first_chunk = array_slice($array, 0, $first_chunk_size);
    $chunks = array_chunk(array_slice($array,$first_chunk_size),3);
    array_unshift($chunks, $first_chunk);
    
    var_dump($chunks);
    

    (显然这段代码可以通过不一步一步地做所有事情来简化)


    编辑: 阅读您的 cmets 到其他回复后,您可以稍微修改此方法并将其转换为 recursive 函数。通过一些代码清理,。它可能看起来像这样:

    $array = [
        'a', 'b', 'c', 'd', 'e', 'f', 'g'
    ];
    
    function custom_array_chunk ($array) {
        $first_chunk_size = count($array) % 3;
        if ($first_chunk_size == 0) {
            $chunks = array_chunk($array, 3);
        } else {
            $chunks = custom_array_chunk(array_slice($array,2));
            array_unshift($chunks, array_slice($array, 0, 2));
        }
        return $chunks;
    }
    
    var_dump(custom_array_chunk($array));
    

    这适用于两种情况,“剩余”的 1 和 2 个元素,并且会产生您告诉我们的内容。

    Demo

    【讨论】:

    • 你不需要计算$chunk_elements,因为count($array) % 3会返回你需要的。
    • 等等,没关系。我理解你的评论。你是对的。
    • 相应编辑。
    • 抱歉,我不会说西班牙语。
    • 无论哪种方式@CristianMeza,请在上面的回复中查看我的编辑。
    【解决方案2】:

    您可以先使用array_reverse 反转数组,然后使用array_chunk。然后反转内部数组,再反转外部数组:

    $array = array(
        'a',
        'b',
        'c',
        'd',
        'e',
        'f',
        'g',
        'h'
    );
    $array = array_reverse($array);
    $chunk = array_chunk($array, 3);
    $array = array_map('array_reverse', $chunk);
    print_r(array_reverse($array));
    

    Demo

    结果

    Array
    (
        [0] => Array
            (
                [0] => a
                [1] => b
            )
    
        [1] => Array
            (
                [0] => c
                [1] => d
                [2] => e
            )
    
        [2] => Array
            (
                [0] => f
                [1] => g
                [2] => h
            )
    
    )
    

    【讨论】:

    • 感谢您的帮助。我还有一个问题,如果块的最后一行只有一个元素,我怎样才能只取第一行的一个元素(最后一个元素)并将其向下移动?谢谢
    • @CristianMeza 如果有一个只有一个元素的块,听起来你想合并这两个块?对我来说,这听起来像是一个单独的问题。
    • @cmbuckley 我认为他实际上希望在第一个块和最后一个块中至少有 2 个元素,更喜欢最后一个块有 3 个而不是第一个。请参阅我的回复以获取解决方案。
    • @CristianMeza 不太清楚你的意思。这听起来像是一个不同的问题。比如:3v4l.org/8U52a
    • @CristianMeza 而不是我们猜测,如果您发布具有预期输出的不同问题,这是获得最佳答案的最简单方法。
    【解决方案3】:

    从功能上来说,multiple array_reverse 的做法是很好理解的:

    $chunk = array_reverse(array_map('array_reverse', array_chunk(array_reverse($array), 3)));
    

    但是,它非常昂贵,尤其是对于较大的阵列。另一种方法是从数组末尾切出元素并将它们添加到分块数组中:

    $size = 3;
    $chunk = array();
    while (count($array) > 0) {
        array_unshift($chunk, array_slice($array, -$size));
        $array = array_slice($array, 0, -$size);
    }
    

    这对于您的数组来说大约快 20 倍(超过 100k 次迭代),对于包含 600 多个项目的数组来说大约快 1000 倍。

    【讨论】:

      【解决方案4】:

      您可以在数组中添加空数据,以符合您的需要。

      然后删除这些前置数据。

      $chunk = 3;
      $nbToPrepend = ($chunk - count($array) % $chunk);
      $prepend = array_fill(0, $nbToPrepend, null);
      $result = array_chunk(array_merge($prepend, $array), $chunk);
      $result[0] = array_slice($result[0], $nbToPrepend);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-09-27
        • 2011-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-17
        • 2012-01-05
        相关资源
        最近更新 更多