【问题标题】:Sort an associative array by group with random group ordering使用随机组排序按组对关联数组进行排序
【发布时间】:2018-08-23 01:14:15
【问题描述】:

我有一个关联数组键/值来指示一个组。我想对数组进行洗牌,使组按随机顺序排列,但组中的项目仅在其组内洗牌。换句话说,我想采取这样的方式:

[
    [
        "name" => "Buffy",
        "group" => 1
    ],
    [
        "name" => "Willow",
        "group" => 1
    ],
    [
        "name" => "Xander",
        "group" => 2
    ],
    [
        "name" => "Giles",
        "group" => 2
    ],
    [
        "name" => "Tara",
        "group" => 3
    ],
    [
        "name" => "Angel",
        "group" => 3
    ],
    [
        "name" => "Spike",
        "group" => 3
    ]
]

然后返回一些更像这样的东西:

[
    [
        "name" => "Spike",
        "group" => 3
    ]
    [
        "name" => "Angel",
        "group" => 3
    ],
    [
        "name" => "Tara",
        "group" => 3
    ],
    [
        "name" => "Willow",
        "group" => 1
    ],
    [
        "name" => "Buffy",
        "group" => 1
    ],
    [
        "name" => "Xander",
        "group" => 2
    ],
    [
        "name" => "Giles",
        "group" => 2
    ],
]

我意识到这可能通过两个或三个排序来实现,但如果这可以通过单个 usort 来完成,那就太好了。

【问题讨论】:

  • 这是一个有趣的问题,但我想问一下,为什么你有示例中的初始结构?如果你想与组一起做事,为什么不使用:[ "group" => 1, "names" => [ "Buffy", "Willow" ] ]

标签: php sorting shuffle


【解决方案1】:

基本上,我的解决方案会打乱输入数组,临时重组输入数组以收集具有相同group 值的子数组,然后将数据返回到其原始结构。

代码:(Demo)

shuffle($data);                         // randomize all subarrays
foreach ($data as $set) {
    $grouped[$set['group']][] = $set;   // merge subarrays on group value
}
$output = [];
foreach($grouped as $group) {
    array_push($output, ...$group);     // return to original array structure
}
var_export($output);

*注意...(splat 运算符)允许array_push() 单独存储所有子数组(每个组内)以生成原始结构。

可能的输出:

array (
  0 => 
  array (
    'name' => 'Xander',
    'group' => 2,
  ),
  1 => 
  array (
    'name' => 'Giles',
    'group' => 2,
  ),
  2 => 
  array (
    'name' => 'Willow',
    'group' => 1,
  ),
  3 => 
  array (
    'name' => 'Buffy',
    'group' => 1,
  ),
  4 => 
  array (
    'name' => 'Spike',
    'group' => 3,
  ),
  5 => 
  array (
    'name' => 'Tara',
    'group' => 3,
  ),
  6 => 
  array (
    'name' => 'Angel',
    'group' => 3,
  ),
)

【讨论】:

  • 这些数据是否偶然来自查询的结果集?
【解决方案2】:

试试……

$groups = [];
foreach (array_unique(array_column($myar, 'group')) as $k) $groups[$k] = rand();
foreach (array_keys($myar) as $k) $myar[$k]['rnd'] = rand();
usort($myar, function($a, $b) use ($groups) {
    if ($gdif = $groups[$b['group']] - $groups[$a['group']]) return $gdif;
    return $b['rnd'] - $a['rnd'];
    });
foreach (array_keys($myar) as $k) unset($myar[$k]['rnd']);

print_r($myar);

使用您的数据运行,这是一个结果...

Array
(
    [0] => Array
        (
            [name] => Buffy
            [group] => 1
        )

    [1] => Array
        (
            [name] => Willow
            [group] => 1
        )

    [2] => Array
        (
            [name] => Angel
            [group] => 3
        )

    [3] => Array
        (
            [name] => Tara
            [group] => 3
        )

    [4] => Array
        (
            [name] => Spike
            [group] => 3
        )

    [5] => Array
        (
            [name] => Giles
            [group] => 2
        )

    [6] => Array
        (
            [name] => Xander
            [group] => 2
        )

)

【讨论】:

  • 此代码也不会随机化组的顺序。
  • @尼克。谢谢。错过了。给我几分钟,我会解决这个问题和其他一些问题。
猜你喜欢
  • 2021-06-10
  • 2013-01-28
  • 1970-01-01
  • 2011-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多