我需要从嵌套到另一个数组的数组中取消设置元素,其方式是只保留第一个N
元素(预定义N
)。只有具有数字索引的元素才会受到影响。
输入数组:
Array
(
[0] => Array (
[a] => 'w'
[b] => Array (
[0]=> 'x'
[1]=> 'x'
[2]=> 'x'
)
)
[1] => Array (
[a] => 'y'
)
[2] => Array (
[0] => 'z'
[1] => 'z'
[2] => 'z'
)
)
所需的输出(N=2
):
Array
(
[0] => Array (
[a] => 'w'
[b] => Array (
[0]=> 'x'
[1]=> 'x'
)
)
[1] => Array (
[a] => 'y'
)
)
根据上面的定义,只有[0][b][2]
和[2]
未设置,因为它们有一个数字索引,因为它们都重写了各自数组的第3个元素。
答案 0 :(得分:5)
没有经过测试,但这样的事情可能有用。
function myFunc(&$array){
foreach($array as $key=>&$value){
if(is_array($value)){
myFunc($value);
}
if(is_numeric($key) && $key > 1){
unset($array[$key]);
}
}
}
关于array_walk。 php.net说:
程序员无法添加,取消设置或 重新排序元素。如果回调了 不尊重这个要求, 这个功能的行为是 未定义,不可预测。
答案 1 :(得分:1)
给自己写一个完全符合你想要的功能。然后记录该函数,如果您需要在大约两周内使用它,您可能想知道该函数到底在做什么。
我这样说是因为您想要处理的数据结构似乎非常具体。所以值得将它封装在一个函数中,以隐藏复杂性。正确命名函数。
在函数内部,您可以以各种方式处理数据,并具备您需要制定的各种条件。来自外部的参数可以作为函数参数传递。返回值是您希望实现的结果。
答案 2 :(得分:1)
这对我有用,也许不是最干净的代码。
$array = array
(
array(
'a' => 'w',
'b' => array('x','x','x')
),
array(
'a' => 'y'
),
array(
'z','z','z'
)
);
function recurse_and_strip ($array, &$size=2)
{
foreach ($array as $key => &$element)
{
if (is_hash($element))
{
$element = recurse_and_strip($element,$size);
} else if (is_array($element))
{
$deletefrom = false;
// now the tricky part.. see how many must be deleted
for ($i=0; $i < count($element); $i++ )
{
if ($size == 0)
{
echo "Delete from " . $i;
$deletefrom = $i;
break 1;
}
$size--;
}
if ($deletefrom !== false)
{
if ($deletefrom == 0)
{
unset($array[$key]);
} else {
array_splice($element,$deletefrom);
}
}
}
}
return $array;
}
// source http://www.benjaminkeen.com/?p=23
function is_hash($var)
{
if (!is_array($var))
return false;
return array_keys($var) !== range(0,sizeof($var)-1);
}
var_dump(recurse_and_strip($array,2));
答案 3 :(得分:1)
array_walk_recursive
本身无法达到你想要的效果。即使你可以通过引用传递数组,在回调中取消设置变量只会在该范围内取消设置。
但是,您可以使用walk_recursive_remove功能:
/**
* http://uk1.php.net/array_walk_recursive implementation that is used to remove nodes from the array.
*
* @param array The input array.
* @param callable $callback Function must return boolean value indicating whether to remove the node.
* @return array
*/
function walk_recursive_remove (array $array, callable $callback) {
foreach ($array as $k => $v) {
if (is_array($v)) {
$array[$k] = walk_recursive_remove($v, $callback);
} else {
if ($callback($v, $k)) {
unset($array[$k]);
}
}
}
return $array;
}
您需要使用$callback
实现自己的逻辑以取消设置特定值。
答案 4 :(得分:0)
这是修改叶子所属数组的更通用的解决方案。您可以取消设置当前密钥,或添加同级兄弟等。
/**
* Modified version of array_walk_recursive that passes in the array to the callback
* The callback can modify the array or value by specifying a reference for the parameter.
*
* @param array The input array.
* @param callable $callback($value, $key, $array)
*/
function array_walk_recursive_array(array &$array, callable $callback) {
foreach ($array as $k => &$v) {
if (is_array($v)) {
array_walk_recursive_array($v, $callback);
} else {
$callback($v, $k, $array);
}
}
}