从 PHP 中的数组中删除切片
Remove slices from array in PHP
我有一个 PHP 数组,我想按照以下规则删除元素切片:当一个元素有 visible=0
时,我想删除元素和下面的 elements
在它之后,不管它们是否可见。
在这个例子中,我想删除 two
、three
、four
、six
和 seven
$categories = array(
array('id'=>'one','visible'=>1,'elements'=>2),
array('id'=>'two','visible'=>0,'elements'=>2),
array('id'=>'three','visible'=>0,'elements'=>1),
array('id'=>'four','visible'=>1,'elements'=>3),
array('id'=>'five','visible'=>1,'elements'=>2),
array('id'=>'six','visible'=>0,'elements'=>1),
array('id'=>'seven','visible'=>1,'elements'=>3),
array('id'=>'eight','visible'=>1,'elements'=>2)
);
我试过以下代码段
foreach($categories as $i=>$data)
{
if($data['visible']==0)
{
array_splice($categories, $i, $data['elements']);
}
}
这是我切片后的预期结果和实际结果
- 预计:
one
、five
、eight
- 实际:
one
、four
、five
、seven
、eight
我错过了什么?
运行 到 $categories
使用简单的 for()
循环,将可见项目复制到新列表 ($cat
),跳过不可见项目和指定跟随它们的项目数:
// Generate the filtered list here
$cat = array();
$count = count($categories);
for ($i = 0; $i < $count; $i ++) {
$data = $categories[$i];
if ($data['visible']) {
// Copy visible item
$cat[] = $data;
} else {
// Do not copy and skip the specified number of extra items
$i += $data['elements'];
}
}
echo("Expected: one, five, eight\n");
echo('Actual : '.implode(', ', array_column($cat, 'id'))."\n");
更新
如果您使用 array_splice()
删除正确数量的项目,您的解决方案也有效:它们是 1 + $data['elements']
; 1
是索引 $i
处的项目和接下来的 $data['elements']
项。
foreach($categories as $i=>$data)
{
if($data['visible']==0)
{
array_splice($categories, $i, 1 + $data['elements']);
}
}
很简单:
$length = count($categories);
$results = array();
for ($i = 0; $i < $length; $i++) {
# just skip!
if ($categories[ $i ]['visible'] == 0) {
$i = ( $i + $categories[ $i ]['elements'] );
} else {
array_push($results, $categories[$i]);
}
}
还有几个选择,使用 array_column
(>php5.5.0) 和 array_filter
:
foreach (array_column($categories, 'visible') as $k => $v) {
if (!$v) {
$categories[$k] = $categories[$k++] = null;
}
}
$result = array_filter($categories);
var_dump($result);
或 array_walk
array_walk(array_column($categories, 'visible'), function ($v, $k) use (&$categories) {
if (!$v) {
$categories[$k] = $categories[$k++] = null;
}
});
$result = array_filter($categories);
var_dump($result);
我有一个 PHP 数组,我想按照以下规则删除元素切片:当一个元素有 visible=0
时,我想删除元素和下面的 elements
在它之后,不管它们是否可见。
在这个例子中,我想删除 two
、three
、four
、six
和 seven
$categories = array(
array('id'=>'one','visible'=>1,'elements'=>2),
array('id'=>'two','visible'=>0,'elements'=>2),
array('id'=>'three','visible'=>0,'elements'=>1),
array('id'=>'four','visible'=>1,'elements'=>3),
array('id'=>'five','visible'=>1,'elements'=>2),
array('id'=>'six','visible'=>0,'elements'=>1),
array('id'=>'seven','visible'=>1,'elements'=>3),
array('id'=>'eight','visible'=>1,'elements'=>2)
);
我试过以下代码段
foreach($categories as $i=>$data)
{
if($data['visible']==0)
{
array_splice($categories, $i, $data['elements']);
}
}
这是我切片后的预期结果和实际结果
- 预计:
one
、five
、eight
- 实际:
one
、four
、five
、seven
、eight
我错过了什么?
运行 到 $categories
使用简单的 for()
循环,将可见项目复制到新列表 ($cat
),跳过不可见项目和指定跟随它们的项目数:
// Generate the filtered list here
$cat = array();
$count = count($categories);
for ($i = 0; $i < $count; $i ++) {
$data = $categories[$i];
if ($data['visible']) {
// Copy visible item
$cat[] = $data;
} else {
// Do not copy and skip the specified number of extra items
$i += $data['elements'];
}
}
echo("Expected: one, five, eight\n");
echo('Actual : '.implode(', ', array_column($cat, 'id'))."\n");
更新
如果您使用 array_splice()
删除正确数量的项目,您的解决方案也有效:它们是 1 + $data['elements']
; 1
是索引 $i
处的项目和接下来的 $data['elements']
项。
foreach($categories as $i=>$data)
{
if($data['visible']==0)
{
array_splice($categories, $i, 1 + $data['elements']);
}
}
很简单:
$length = count($categories);
$results = array();
for ($i = 0; $i < $length; $i++) {
# just skip!
if ($categories[ $i ]['visible'] == 0) {
$i = ( $i + $categories[ $i ]['elements'] );
} else {
array_push($results, $categories[$i]);
}
}
还有几个选择,使用 array_column
(>php5.5.0) 和 array_filter
:
foreach (array_column($categories, 'visible') as $k => $v) {
if (!$v) {
$categories[$k] = $categories[$k++] = null;
}
}
$result = array_filter($categories);
var_dump($result);
或 array_walk
array_walk(array_column($categories, 'visible'), function ($v, $k) use (&$categories) {
if (!$v) {
$categories[$k] = $categories[$k++] = null;
}
});
$result = array_filter($categories);
var_dump($result);