使用随机分组顺序按组对关联数组进行排序

时间:2018-08-23 01:14:16

标签: php sorting shuffle

我有一个表示组的关联数组键/值。我想对数组进行混洗,以使组以随机顺序排列,但仅对组中的项进行混洗。换句话说,我想采取这样的做法:

[
    [
        "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完成,那将是很棒的。

2 个答案:

答案 0 :(得分: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,
  ),
)

答案 1 :(得分:0)

尝试...

$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
        )

)