我有一个看起来像这样的简单数组:
Array (
[0] => Array (
[id] => 8692
[name] => d
)
[1] => Array (
[id] => 8691
[name] => c
)
[2] => Array (
[id] => 8690
[name] => b
)
[3] => Array (
[id] => 8689
[name] => a
)
[4] => Array (
[id] => 8500
[name] => d
)
[5] => Array (
[id] => 8499
[name] => c
)
[6] => Array (
[id] => 8498
[name] => b
)
[7] => Array (
[id] => 8497
[name] => a
)
)
这个数组很长,所以我只包含前4个项目给你一个想法。
我的问题是我需要数组格式为
a,b,c,d,a,b,c,d
目前格式如下:
d,c,b,a,d,c,b,a
我的意思是['name']值,它是a,b,c或d。
所以我需要反转数组中的每4个项目。
我试图实现这一目标,但每次都以失败告终。而循环。
答案 0 :(得分:7)
您可以使用array_chunk
,array_merge
和array_reverse
执行此操作:
$finalArray = array();
$arrays = array_chunk($myArray, 4);
foreach ($arrays as $array) {
$finalArray = array_merge($finalArray, array_reverse($array));
}
答案 1 :(得分:3)
这里的所有答案虽然完全有效,但几乎都是O(n^2)
的顺序。所以我想我会给你一个O(n / 2)
时间复杂度的解决方案作为替代,以防万一你关心性能。该解决方案还仅使用O(n + n + k)
空间复杂度(就地交换)。
由于要求是反转值的顺序,我忽略了密钥并将解决方案基于数组始终为0索引的约束。
要解决这个问题,我们可以将解决方案概括为一个简单的数组反转,这需要使用就地交换进行简单的O(n/2)
操作。我们可以使用两个计数器简单地实现这一点,从数组的开头开始$i
,从数组的末尾开始$j
。因此,我们可以将$arr[$i]
处的值与$arr[$j]
处的值进行交换,然后在每一步中递增$i
并递减$j
。
function reverseArray(Array $arr) {
for($i = 0, $j = count($arr); $i < $j; $i++, $j--) {
$tmp = $arr[$j];
$arr[$j] = $arr[$i];
$arr[$i] = $tmp;
}
return $arr;
}
现在,要应用更多特定的解决方案,只反转数组中每个4个元素的组,我们只需在4个值的分区中拆分数组,并且只在每个分区处反转一时间通过将reverseArray()
和$i
计数器的起始位置和结束位置更改为仅在每个分区内反转,仅扩展$j
上面的示例。
因此,我们通过为分区大小添加另一个循环来到达O(n / 2)
解决方案,并保留内部循环与前面的示例。
function reverseArrayPartition(Array $arr, $partitionSize = 4) {
$end = count($arr);
// reverse only one partition at a time
for($start = 0; $start < $end; $start += $partitionSize ) {
$from = $start;
$to = $start + $partitionSize - 1;
for($i = $from, $j = $to; $i < $j; $i++, $j--) {
// swap the transposing values
$tmp = $arr[$j];
$arr[$j] = $arr[$i];
$arr[$i] = $tmp;
}
}
return $arr;
}
$arr = [4,3,2,1,4,3,2,1];
var_dump(reverseArrayPartition($arr)); // expected [1,2,3,4,1,2,3,4]
这适用于任何$partitionSize
的任何数组大小,因此如果您尝试在非常大的数组上执行此操作,效率会很高。
答案 2 :(得分:2)
您可以使用for
迭代数组并每次增加4并将当前偏移保持在其他变量中并使用array_slice
来获取当前的数组切片并使用{{1 }}
我在考虑这样的事情:
array_reverse
for中的所有内容都可以简化为:
$step = 4;
$offset = 0;
$new_arr = []; //Here we create the new array.
for($i=0; $i<count($arr); $i+=$step) {
$part_of_array = array_slice($arr, $offset, $step);
$part_reverse = array_reverse($part_of_array);
$new_arr = array_merge($new_arr, $part_reverse);
$offset += $step;
}
print_r($new_arr); //Here will be the array as you expected.
答案 3 :(得分:-1)
不是每4次攻击,基于name
值
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
/**
*/
$in = [
['name'=>'d','id'=>1]
, ['name'=>'c','id'=>12]
, ['name'=>'b','id'=>13]
, ['name'=>'a','id'=>14]
, ['name'=>'d','id'=>15]
, ['name'=>'c','id'=>16]
, ['name'=>'b','id'=>17]
, ['name'=>'a','id'=>18]
];
$last = PHP_INT_MAX;
$toReverse = [];
$out = [];
foreach ($in as $value) {
$p = ord($value['name']);
if ( $p < $last ) {
//echo 'ToReverse',var_export($value,true),"\n";
$toReverse[] = $value;
}
else {
$out = array_merge($out,array_reverse($toReverse));
//echo 'Join',var_export($out,true),"\n";
$toReverse = [$value];
}
$last = $p;
}
$out = array_merge($out,array_reverse($toReverse));
print_r($out);