如果我们有一个具有整数键的四维立方体,并且我们想通过保持三维键$i3固定在某个值$i30来将四维数组转换为3D数组,我们可以这样做:
// ARRAY REMOVE 3RD INDEX IN 4D
function array_remove($a,$i30){
$n1=count($a);
$n2=count($a[0]);
$n3=count($a[0][0]);
$n4=count($a[0][0][0]);
$a1=array();
for ($i1=0;$i1<$n1;$i1++){
$a1[$i1]=array();
for ($i2=0;$i2<$n2;$i2++){
$a1[$i1][$i2]=array();
for ($i4=0;$i4<$n4;$i4++){
$a1[$i1][$i2][$i4]=$a[$i1][$i2][$i30][$i4];
}
}
}
return $a1;
}
我如何扩展这个函数来删除任何维度,即删除$ik $ik0 $array_remove($a,$ik,$ik0),或任何维度的数组不是4D只有$array_remove($a,$n,$ik,$ik0)?
我忍不住了。
给定一个n维数组,返回一个n-1维的数组,使用替换维度的特定值:
$source = [
1 => [
'a' => ['p', 'q', 'r'],
'b' => ['s', 't', 'u'],
'c' => ['v', 'w', 'x'],
],
2 => [
'a' => ['e', 'f', 'g'],
'b' => ['h', 'i', 'j'],
'c' => ['k', 'l', 'm'],
],
];
$result = array_select($source, 2, 'b');
$result
现在:
[
1 => ['s', 't', 'u'],
2 => ['h', 'i', 'j'],
]
第二个维度已被替换为该维度中索引'b'
的值。
任意深度的嵌套循环建议递归-遍历数组到我们执行手术的深度:
function array_select(array $source, int $dimension, $value) {
// TODO: before starting recursion, make sure that $dimension >=1
// and the actual depth of $source is > $dimension
if ($dimension === 1) {
// return the value at that depth, empty if not set
return $source[$value] ?? [];
} else {
foreach ($source as $index => $subset) {
$source[$index] = array_select($subset, $dimension - 1, $value);
}
return $source;
}
}
一旦递归达到所需的深度,它只需要返回给定值处的任何值。
这实际上比原始约束版本的代码行数更少。
删除指示的索引类似:
$result = array_remove($source, 2, 'b');
$result
是现在:
[
1 => [
'a' => ['p', 'q', 'r'],
'c' => ['v', 'w', 'x'],
],
2 => [
'a' => ['e', 'f', 'g'],
'c' => ['k', 'l', 'm'],
],
]
要删除指定的索引,当到达"depth of surgery"时,返回除指定索引外的所有索引的数组:
function array_remove(array $source, int $dimension, $value) {
// TODO: before starting recursion, make sure that $dimension >=1
// and the actual depth of $source is > $dimension
if ($dimension === 1) {
// return all but the value at that depth
return array_filter($source, function ($key) use ($value) {
return $key != $value;
}, ARRAY_FILTER_USE_KEY);
} else {
foreach ($source as $index => $subset) {
$source[$index] = array_remove($subset, $dimension - 1, $value);
}
return $source;
}
}