【问题标题】:Rearrange PHP Array, reorder 1, 2, 3, 4, 5, 6, 7, 8, 9 to 1, 4, 7, 2, 5, 8, 3, 6, 9重新排列 PHP 数组,将 1、2、3、4、5、6、7、8、9 重新排序为 1、4、7、2、5、8、3、6、9
【发布时间】:2022-10-08 11:44:46
【问题描述】:

事情是这样的,我有一个数组,我想按每第三个项目重新排序。所以它是第 1、第 4、第 7,然后是第 2、第 5、第 8 和第 3、第 6、第 9。

由此:

$items = array('1','2','3','4','5','6','7','8','9');

对此:

$reordered_items = array('1','4','7','2','5','8','3','6','9');

或者它也可以是 3 个单独的数组。像这样:

['1', '4', '7']
['2', '5', '8']
['3', '6', '9']

尝试过array_chunk($items, count($items) / 3),但它只返回相同的数组,分为 3 个相等的数组。

['1', '2', '3']
['4', '5', '6']
['7', '8', '9']

我不知道我是否应该使用array_chunk 然后使用其他东西来实现我想要的。因此,让我知道您对此有何看法。

UPD:输入数组中不必正好是 9 个项目。它可以更短或更长,关键是它必须每找到第三个项目,只要找到任何等等......

因此,如果有 10 个项目:

$items = array('1','2','3','4','5','6','7','8','9','10');

输出应该是这样的:

$reordered_items = array('1','4','7','10','2','5','8','3','6','9');

谢谢!

【问题讨论】:

  • 数组是否总是正好 9 个项目长,或者是否有一个规则来规定更短或更长的数组应该是什么样子?
  • @IMSoP 不完全是 9 项,我只是将其用作参考。关键是第三条。因此,即使有 5 个项目,它也应该像这样订购:1、4、2、5、3。我什至不知道这是否可能:D
  • 示例输入数组是否总是“排序”的,或者仅仅是为了举例?
  • @mardubbles 总是排序的
  • 使用数组值

标签: php arrays algorithm


【解决方案1】:

我能想到的最简单的方法是循环列表三遍:

  • 从元素 0 开始,跳过 3,超过列表末尾时停止
  • 从元素 1 开始,跳过 3,超过列表末尾时停止
  • 从元素 2 开始,跳过 3,超过列表末尾时停止

这可以使用 C 风格的for loop syntax 轻松实现:

$maxKey = count($items) - 1;
$rearrangedItems = [];
for ( $key=0; $key<=$maxKey; $key+=3 ) {
    $rearrangedItems[] = $items[$key];
}
for ( $key=1; $key<=$maxKey; $key+=3 ) {
    $rearrangedItems[] = $items[$key];
}
for ( $key=2; $key<=$maxKey; $key+=3 ) {
    $rearrangedItems[] = $items[$key];
}

如果您需要推广到不同的偏移量,您可以将整个内容放入外部循环而不是复制和粘贴:

$offset = 3;
$maxKey = count($items) - 1;
$rearrangedItems = [];
for ( $start=0; $start<$offset; $start++ ) {
    for ( $key=$start; $key<=$maxKey; $key+=$offset ) {
        $rearrangedItems[] = $items[$key];
    }
}

【讨论】:

    【解决方案2】:

    尝试这个

    $items = array('1','2','3','4','5','6','7','8','9');
    $tmp = [];
    for ($i = 0; $i < count($items); $i++) {
        $tmp[$i%3][] = $items[$i];
    }
    $result = array_merge($tmp[0], $tmp[1], $tmp[2]);
    print_r($result);
    

    【讨论】:

    • 简要说明其工作原理会很好,以便读者了解如何使该技术适应不同的情况。
    • @IMSoP 这个和你提供的例子一样好用。但是在您的示例中,这个只使用一个 for 循环而不是 2
    • 我不认为@IMSoP 抱怨你的代码,只是你没有提供关于为什么应该使用 OP 的信息尝试这个?好的答案将始终解释所做的事情以及这样做的原因,不仅对于 OP,而且对于可能会发现此问题并正在阅读您的答案的 SO 的未来访问者。如果回答得很好,也许他们会支持它。
    • 不过我喜欢这段代码。但是因为没有解释,我将接受@IMSoP 的回答
    【解决方案3】:

    尝试这个,

    $items = array('1','2','3','4','5','6','7','8','9');
    $tmp = [];
    for ($i = 0; $i < count($items); $i++) {
        $tmp[$i%3][] = $items[$i];
    }
    $result = call_user_func_array('array_merge', $tmp);
    dd($result);
    

    输出 :

    数组('1','4','7','2','5','8','3','6','9')

    【讨论】:

    • 简要说明其工作原理会很好,以便读者了解如何使该技术适应不同的情况。
    【解决方案4】:

    很简单:

    $items = array('1','2','3','4','5','6','7','8','9');
    
    $items = array_chunk($items, 3); # Split into arrays of size 3
    $items = array_map(null, ...$items); # Transpose the arrays
    $items = array_merge(...$items); # Merge the arrays again
    
    print_r($items);
    

    【讨论】:

    • 如果甚至没有块大小,则会有空值,例如向数组中再添加一个元素
    • 是的,@Justinas 是对的,如果我添加另一个项目,将有 2 个其他项目的价值等于 null
    • 简要说明其工作原理会很好,以便读者了解如何使该技术适应不同的情况。
    【解决方案5】:

    我认为这个任务只不过是一个排序任务。

    将每个值除以 3 时按其模值排序。如果结果为 0,则回退到 3。没有什么奢侈的,只是简单、直接、逻辑、D.R.Y。编程。

    代码:(Demo)

    array_multisort(
        array_map(fn($v) => $v % 3 ?: 3, $items),
        $items
    );
    

    【讨论】:

      猜你喜欢
      • 2021-05-30
      • 1970-01-01
      • 2021-02-15
      • 1970-01-01
      • 2011-09-08
      • 2012-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多