pedroz
September 24, 2012, 5:13pm
1
[0]=>
array {
"id" => 11,
"rule"=> "rule 1"
},
[1]=>
array {
"id" => 40,
"rule"=> "rule 2"
}
[3]=>
array {
"id" => 55,
"rule"=> "rule 3"
}
[4]=>
array {
"id" => 40,
"rule"=> "rule 4"
}
How am I able to unset the elements with id = 40 to get the following array?
[0]=>
array {
"id" => 11,
"rule"=> "rule 1"
},
[1]=>
array {
"id" => 55,
"rule"=> "rule 3"
}
Do I need to do a foreach cycle / array check / unset?
Or is there any php function for it?
I have a feeling this is wrong as I am very rusty with PHP, but the right direction that you or someone else can finish off?
foreach ($array as $rule) {
if $rule['rule'] = "rule 2' then {
unset($rule['id']);
}
}
cpradio
September 24, 2012, 6:48pm
3
I’ve been thinking this one over for a few hours, and then it hit me. I’m trying to think of something clever… Clever, is a dangerous thing. Sometimes from a readability standpoint the most simple solution (as you described and what K.Wolfe tried to implement) is usually the best solution.
To take K.Wolfe’s code and make it workable
foreach ($rules as $key => $rule) {
if ($rule['id'] === 40) {
unset($rules[$key]);
}
}
QMonkey
September 24, 2012, 7:23pm
4
I agree.
Here’s another way to go but you’re creating a function. I do like how the one line says it all.
function id_not_40( $v ) {
return $v['id'] != 40;
}
$new_array = array_filter( $orig_array, "id_not_40" );
Or all in one but less readable in my opinion.
$new_array = array_filter( $orig_array, function( $v ) { return $v['id'] != 40; } );
and you may want to call array_values() on it after to re-index the array if desired.
QMonkey:
I agree.
Here’s another way to go but you’re creating a function. I do like how the one line says it all.
function id_not_40( $v ) {
return $v['id'] != 40;
}
$new_array = array_filter( $orig_array, "id_not_40" );
Or all in one but less readable in my opinion.
$new_array = array_filter( $orig_array, function( $v ) { return $v['id'] != 40; } );
and you may want to call array_values() on it after to re-index the array if desired.
If you going this route, then you may as well finish it off…
function id_not_in( $v, $filter ) {
return $v['id'] != $filter;
}
$new_array = array_filter( $orig_array, "id_not_in" );
QMonkey
September 24, 2012, 8:48pm
6
Well, now we’re getting to be complex again. But for the sake of exercise…
/**
* Filters a multi-dimentional array based on matching (or not)
* a key/value pair of the items
*
* @param array $data
* @param string $k
* @param string $v
* @param boolean $match
*
* @return array
*/
function special_array_filter( $data, $k, $v, $match = true ) {
$filter = function ( $item ) use ( $k, $v, $match ) {
return ( isset( $item[ $k ] ) && $item[ $k ] == $v ) ? $match : !$match;
};
return array_filter( $data, $filter );
}
// usage:
$orig_array = array(
array (
"id" => 11,
"rule"=> "rule 1"
),
array (
"id" => 40,
"rule"=> "rule 2"
),
array (
"id" => 55,
"rule"=> "rule 3"
),
array (
"id" => 40,
"rule"=> "rule 4"
) );
$new_array = special_array_filter( $orig_array, 'id', 40, false );
Don’t try this at home - unless you need to do something like that in more than one place. But really, just go with the foreach thing, though I do like my first array_filter solution myself.
<?php
class Filter extends FilterIterator
{
public function accept()
{
$current = $this->current();
return 40 != $current['id'];
}
}
$array = array(
array('id' => 12, 'name' => 'foo'),
array('id' => 40, 'name' => 'foo'),
);
foreach(new Filter(new ArrayIterator($array)) as $item)
{
echo $item['id'], ' - ', $item['name'], PHP_EOL;
}
/*
12 - foo
*/
Or…
<?php
class Filter extends FilterIterator
{
public function accept()
{
$current = $this->current();
return 40 != $current['id'];
}
}
$array = array(
array('id' => 12, 'name' => 'foo'),
array('id' => 40, 'name' => 'foo'),
);
$array = iterator_to_array(new Filter(new ArrayIterator($array)));
Again, not quite the easiest way to do this; but I like it.
cpradio
September 24, 2012, 9:13pm
8
QMonkey:
Here’s another way to go but you’re creating a function. I do like how the one line says it all.
function id_not_40( $v ) {
return $v['id'] != 40;
}
$new_array = array_filter( $orig_array, "id_not_40" );
Or all in one but less readable in my opinion.
$new_array = array_filter( $orig_array, function( $v ) { return $v['id'] != 40; } );
and you may want to call array_values() on it after to re-index the array if desired.
array_filter! I knew there was a function that took a callback but earlier for the life of me I couldn’t find it! I don’t get to use it a lot so I constantly forget about it.
AnthonySterling:
<?php
class Filter extends FilterIterator
{
public function accept()
{
$current = $this->current();
return 40 != $current['id'];
}
}
$array = array(
array('id' => 12, 'name' => 'foo'),
array('id' => 40, 'name' => 'foo'),
);
foreach(new Filter(new ArrayIterator($array)) as $item)
{
echo $item['id'], ' - ', $item['name'], PHP_EOL;
}
/*
12 - foo
*/
Or…
<?php
class Filter extends FilterIterator
{
public function accept()
{
$current = $this->current();
return 40 != $current['id'];
}
}
$array = array(
array('id' => 12, 'name' => 'foo'),
array('id' => 40, 'name' => 'foo'),
);
$array = iterator_to_array(new Filter(new ArrayIterator($array)));
Again, not quite the easiest way to do this; but I like it.
Now that is an interesting solution. Might fall into the “trying to be too clever” paradigm, but I could see uses for it in a much more complicated scenario.