4 回答
TA贡献1863条经验 获得超2个赞
同样的想法是将输入分成 1 和 0,然后只要还有一些东西要输出,就输出 0 和 1。每次输出一个值时,数组都会减少,这会一直持续到两个列表都是空的,所以应该处理不平衡的列表......
$temp = [ 0 => [], 1 => []];
foreach($args as $key=>$value){
$temp[$value['zebra']][] = $key;
}
$output = [];
while ( !empty($temp[0]) || !empty($temp[1]) ) {
if ( !empty($temp[0]) ) {
$next = array_shift($temp[0]);
$output [$next] = $args[$next];
}
if ( !empty($temp[1]) ) {
$next = array_shift($temp[1]);
$output [$next] = $args[$next];
}
}
TA贡献1780条经验 获得超5个赞
这是array_map在单独的数组中抓取 1 和 0 后使用的解决方案:
$args0 = array_filter($args, function ($arg) {
return $arg['zebra'] === 0;
});
$args1 = array_filter($args, function ($arg) {
return $arg['zebra'] === 1;
});
$result = array_merge(...array_map(static function ($arg0Key, $arg1Key) use ($args0, $args1) {
if ($arg0Key !== null) {
$result[$arg0Key] = $args0[$arg0Key];
}
if ($arg1Key !== null) {
$result[$arg1Key] = $args1[$arg1Key];
}
return $result;
}, array_keys($args0), array_keys($args1)));
print_r($result);
演示:https ://3v4l.org/sfqeq
注意:使用两个array_filter分隔值看起来不错,但循环$args两次;如果初始数组可能有点大,则更喜欢简单的循环。不过,这不是答案的相关部分。
TA贡献1770条经验 获得超3个赞
我可以建议您使用带有比较计数的解构。
第一步,您可以使用zebra = 1和 with收集所有索引zebra = 0:
$zeros = [];
$ones = [];
foreach($args as $let=>$arg){
if ($arg['zebra'] === 1) {
$ones[] = $let;
} else if ($arg['zebra'] === 0) {
$zeros[] = $let;
}
}
现在您可以构造结果数组,例如:
if(abs(count($zeros) - count($ones)) === 1) { // if their difference equal to 1
if (count($ones) > count($zeros)){ // if $ones is bigger
foreach($zeros as $ind=>$let){
$res[$ones[$ind]] = ['zebra' => 1];
$res[$let] = ['zebra' => 0];
$tmp = $ind;
}
$res[$ones[$tmp+1]] = ['zebra' => 1];
} else if (count($ones) < count($zeros)){ // if $zeros is bigger
foreach($ones as $ind=>$let){
$res[$zeros[$ind]] = ['zebra' => 0];
$res[$let] = ['zebra' => 1];
$tmp = $ind;
}
$res[$zeros[$tmp+1]] = ['zebra' => 0];
}
}
输出:
Array
(
[b] => Array
(
[zebra] => 0
)
[a] => Array
(
[zebra] => 1
)
[c] => Array
(
[zebra] => 0
)
[e] => Array
(
[zebra] => 1
)
[d] => Array
(
[zebra] => 0
)
)
演示
如果在 (1,0,1,0,0) 的情况下需要结果,请使用下一个构造函数:
if (count($ones) > count($zeros)){
foreach($ones as $ind=>$let){
if (isset($zeros[$ind])) $res[$zeros[$ind]] = ['zebra' => 0];
$res[$let] = ['zebra' => 1];
}
} else if (count($zeros) > count($ones)){
foreach($zeros as $ind=>$let){
$res[$let] = ['zebra' => 0];
if (isset($ones[$ind])) $res[$ones[$ind]] = ['zebra' => 1];
}
}
输出:
Array
(
[b] => Array
(
[zebra] => 0
)
[a] => Array
(
[zebra] => 1
)
[d] => Array
(
[zebra] => 0
)
[c] => Array
(
[zebra] => 1
)
[e] => Array
(
[zebra] => 0
)
)
TA贡献2021条经验 获得超8个赞
好吧,您可以收集0一个数组中的所有1s' 和另一个数组中的所有 s',然后只需将它们交替添加到新数组中并进行布尔flag检查。
伪代码:
ones = []
zeroes = []
for($args as key => value)
value['key'] = key // to preserve the key as well for later restoration
if(value['zebra'] == 1)
ones.push(value)
else
zeroes.push(value)
result = []
flag = true // to decide to pop from ones or zeroes
while(sizeof(ones) > 0 || sizeof(zeroes) > 0){
if(sizeof(ones) == 0 || flag === false){
element = zeroes.pop()
result[element['key']] = ['zebra' => element['zebra']]
}else if(sizeof(zeroes) == 0 || flag){
element = ones.pop()
result[element['key']] = ['zebra' => element['zebra']]
}
flag = !flag // to alternately add from either arrays
}
- 4 回答
- 0 关注
- 96 浏览
添加回答
举报