我有一个具有type
属性的对象数组;有5种可能的'类型'。重要的是,元素被插入到数组中,并且应尽可能保留随机性;它只是第三方软件限制,迫使这种非邻接业务。
我想对该数组进行排序,以便没有相邻的值相同,或者,如果事实证明这是不可能的,则确保不可移动的对到达底部。
我试过这个:
function check_adjacency($obj_1, $obj_2) {
return $obj_1->type == $obj_2->type ? 0 : 1; // also tried -1
}
usort($arr, "check_adjacency");
我可以理解为什么这不起作用;没有返回1 vs -1的标准。但我对如何(有效地)在PHP中编写它感到困惑。我也尝试编写自己的函数来实现这一点,但我总是过早完成或无限循环。战略建议和解决方案都欢迎。
更新
请求示例:
为方便起见,我使用了顺序变量名,但实际上这些对象是以type
属性的随机顺序添加到数组中的。
$objs = [ $obj_1, $obj_2, $obj_3, $obj_$4... $obj_300];
foreach($objs as $o) print $o->type
收率:
>> "t2", "t1", "t1", "t2", "t2", "t4", "t3", "t3", "t3", "t5", "t1", "t2"...
理想情况下,排序后会得到类似的东西。
>> "t2", "t1", "t2", "t4", "t3", "t1", "t3", "t2", "t3", "t5", "t1", "t2"
基本上,如果集合中的下一个元素具有与前一个元素相同的type
属性,则将其删除并在此后的最早索引处插入。如果这还没有澄清,请告诉我。
编辑第二个:
想到一个更简单的解释方法。我有很多书 - 小书,中型书和大书。都有不同的头衔;我想要一个书架,上面没有两本相同大小的书籍,而这些书籍则是随机分布的。
答案 0 :(得分:1)
分两步完成。首先创建一个二维数组,其键是type
属性,元素是具有该类型的所有项的数组。然后遍历这些键,从每个组中删除一个项目并将其添加到结果数组中。
// step 1
$arr_by_type = array();
foreach ($arr as $el) {
if (isset($arr_by_type[$el->type])) {
$arr_by_type[$el->type][] = $el;
} else {
$arr_by_type[$el->type] = array($el);
}
}
// step 2
$result = array();
while (!empty($arr_by_type)) {
foreach ($arr_by_type as $type => &$sub_array) {
$result[] = array_pop($sub_array);
if (empty($sub_array)) {
unset($result[$type]);
}
}
}
print_r($result);