Array_search?
$loc = array_search($array, $value);
If ($loc != -1) {
unset($array[$loc]);
}
eg:
$myarray = array(1 => 'tree', 2 => 'fish', 3 => 'horse');
unset($myarray[2]);
print_r($myarray);
Outputs:
Array
(
[1] => tree
[3] => horse
)
Alternatively you can search for the value if they are unique and then
unset:
$key = array_search('horse', $myarray);
if ($key !== false) {
unset($myarray[$key]);
}
print_r($myarray);
Outputs:
Array
(
[1] => tree
)
HTH
- Mike
--
Mike Cochrane
Web Team Leader
gardyneHOLT - design partners
18 Beresford Square Newton
PO Box 3340 Auckland New Zealand
p +64 9 300 3155 f +64 9 302 3349 m 021 545 565
skype gardyneholt_mikec
www.gardyneholt.co.nz
- Mike :-)
Cameron Junge wrote:
>
> Array_search?
>
> $loc = array_search($array, $value);
>
> If ($loc != -1) {
>
> unset($array[$loc]);
>
> }
>
> ------------------------------------------------------------------------
>
> *From:* nzp...@googlegroups.com [mailto:nzp...@googlegroups.com] *On
> Behalf Of *Jochen Daum
> *Sent:* Thursday, 17 April 2008 9:37 a.m.
> *To:* ph...@phpug.org.nz
> *Subject:* [phpug] Smart way to remove item from array (values only)
>
> Hi,
>
> is there a smart way to remove an entry from an array of value without
> looping through it?
>
> I found array_splice, but I would need to loop for the offset I guess?
>
> Regards,
>
> Jochen
>
Heh, hope you don't have any fields with commas in them, or that surname
isn't the last column... is there some reason to avoid just
foreach($array as $key => $val) {
if($val == 'whatever') unset($array[$key]);
}
?
--
Tim Oliver
t...@e2-media.co.nz
Another way would be array_filter
$array = array_filter($array, create_function(‘$v’, ‘return $v !=’.$value.’;));
I keep forgetting about the array functions.
Cam
From: nzp...@googlegroups.com [mailto:nzp...@googlegroups.com] On Behalf Of Jochen Daum
Sent: Thursday, 17 April 2008
10:49 a.m.
To: ph...@phpug.org.nz
Subject: [phpug] Smart way to
remove item from array (values only)
Hi,
Oops, forgot the last single quote:
$array = array_filter($array, create_function(‘$v’, ‘return $v !=’.$value.’;’));
From: nzp...@googlegroups.com [mailto:nzp...@googlegroups.com] On Behalf Of Cameron Junge
Sent: Thursday, 17 April 2008
10:53 a.m.
To: nzp...@googlegroups.com
Subject: [phpug] Re: Smart way to
remove item from array (values only)
But to clear it, just check using is_numeric, and discard/ignore the
numerical index.
automatem
. software solutions |
|
|
Aaron Cooper wrote:
> I found the site where I got this method. With 5 other methods and
> speed benchmarks (this method was the fastest):
> http://lixlpixel.org/php-benchmarks/remove-array-items-by-value/
I just had a look at the results on there and they didn't make sense so
I had to rerun them. I created this:
http://dev.gardyneholt.co.nz/benchmark1.phps
to test them and included that way I would have done it - test5 near the
bottom. I included the 4 tests that have sufficient code to just copy
and paste and test. One of them, "fast for loop", doesn't actually work.
I haven't taken any time to look at these functions or interpret the
results, I'll leave that up to you guys.
Results from running it here:
http://dev.gardyneholt.co.nz/benchmark1.php
array_search in a while loop is fastest in my tests.
Feel free to take the code and test on your one systems. I'd be
interested to know if someone's getting wildly different results.
- Mike
My results are pretty much the same, except Foreach and Explode/Join swap
positions every now and then (More often than not, Explode/Join leads), as
too do the Fast for loop and For loop. But those pairs never swap positions
with the other. The for loops are quite a bit slower.
Surprised at the huge difference the while/array search wins by. Going a bit
off topic now though. I'm sure there is a very good reason why Jochen didn't
want a loop.
Cheers
Aaron
While-search is approx. 50% faster than the for-loop test (ignoring the
non-working fast-for-loop). That's over 500 iterations.
So:
22.24588ms / 500 => 0.0444918ms or approx. 4.4us per iteration.
47.30511ms / 500 => 0.0946102ms or approx. 9.5us per iteration.
The difference is 5.1us. No idea of the error deviation in that result.
No one is going to notice the difference, and who the hell is going to
run a loop over enough items to make that difference noticeable. Even
the difference between 47 & 22 milliseconds isn't going to be
noticeable.
I myself have done some optimizations on code for stuff like this. But,
it's pointless really. Focus on the bigger gains, not the little tiny
ones. Remove most of the bigger bottlenecks & you'll notice the
difference. Remove ones like the above and you'll hardly notice them.
"Premature optimization is the root of all evil." - Donald Knuth.
-----Original Message-----
From: nzp...@googlegroups.com [mailto:nzp...@googlegroups.com] On
Behalf Of Mike Cochrane
Sent: Friday, 18 April 2008 11:20 a.m.
To: nzp...@googlegroups.com
But if someone wants to spend the time testing it based on interest, and
comes up with a clear winning method, does it not help everyone for future
knowledge, regardless of how small a difference it makes?
I mean, most of those methods are similar in the amount of time they take to
type. (bugger all). So if one displays a clear advantage (note I say clear,
not huge), it makes sense to take it into account to me.
Code readability will be the next topic to come up I would say.
So yeah, it is obvious. I think we all spotted the miniscule timings. That
still doesn't detract from the fact that I understand just a little bit more
about the language now.
Again, this topic has way OT now. Jochen never mentioned that his reason for
not using loops was perfomance.
Aaron
----- Original Message -----
From: "Cameron Junge" <cju...@author-it.com>
To: <nzp...@googlegroups.com>
I was just surprised to see someone claim that it was faster to convert
an array to a string, perform string operations and then go back to an
array again - but they were in fact correct in claiming that. And I had
a friend (another nzphpug reader) that pointed out that my solution was
missing from the benchmark so had to compare it.
I do have real cases where there are sometimes 50K+ iterations and so
small gains like this are useful. Although I can't remember ever needing
to remove an array item by value before in real code, that occurs as a
bad thing when I'm conceptualising code - but at least I know how to do
it fast now.
- Mike :-)
Cameron Junge wrote:
> I hate to point out the obvious...
>
> While-search is approx. 50% faster than the for-loop test (ignoring the
> non-working fast-for-loop). That's over 500 iterations.
>
> So:
>
> 22.24588ms / 500 => 0.0444918ms or approx. 4.4us per iteration.
> 47.30511ms / 500 => 0.0946102ms or approx. 9.5us per iteration.
>
> The difference is 5.1us. No idea of the error deviation in that result.
>
> No one is going to notice the difference, and who the hell is going to
> run a loop over enough items to make that difference noticeable. Even
> the difference between 47& 22 milliseconds isn't going to be
> noticeable.
>
> I myself have done some optimizations on code for stuff like this. But,
> it's pointless really. Focus on the bigger gains, not the little tiny
> ones. Remove most of the bigger bottlenecks& you'll notice the
You make valid points... I guess if one was to use as standard a method
that is possibly fractionally faster than another, then that gain
doesn't cost anything (unless it's horribly unreadable/unmaintainable).
Example: I tend to use while(list($key,$value) = each($array)){} instead
of a for loop. It's fractionally faster than a for, and has the
advantage of using less memory (it uses references and a pointer)
[granted, PHP5 allows an array item to be referenced]. I also find it a
bit easier to understand. So a free win, possibly.
Oh, something just jumped into my mind about that while-array_search. Be
careful of an index casting to false (eg: 0). In fact, the method would
fail if the first item was the search item & it had an index of 0.
So the code should be:
function test5($workdata, $item2remove) {
while($key = array_search($item2remove, $workdata) && $key !==
false) {
unset($workdata[$key]);
}
return $workdata;
}
(might be a bit slower with the added comparison...)
Cameron
Aaron Cooper:
- Mike :-)
Also the Explode/Join example doesn't match the last item in the array
and needs a couple more string operations to handle that case and it
fails if the value to remove is the suffix of another value.
eg removing 't' from: array('test', 't') would give array('tes');
So Explode/Join should be used very carefully.
This includes fixes for not matching the first item with 'while
array_search' and not matching the last with 'Explode/join'.
http://dev.gardyneholt.co.nz/benchmark2.php
http://dev.gardyneholt.co.nz/benchmark2.phps
- Mike
Cameron Junge wrote:
> Oh, and another variable to throw into the mix that hasn't been
> mentioned yet: PHP's garbage collector, which runs at random times.
>
> You make valid points... I guess if one was to use as standard a method
> that is possibly fractionally faster than another, then that gain
> doesn't cost anything (unless it's horribly unreadable/unmaintainable).
>
> Example: I tend to use while(list($key,$value) = each($array)){} instead
> of a for loop. It's fractionally faster than a for, and has the
> advantage of using less memory (it uses references and a pointer)
> [granted, PHP5 allows an array item to be referenced]. I also find it a
> bit easier to understand. So a free win, possibly.
>
> Oh, something just jumped into my mind about that while-array_search. Be
> careful of an index casting to false (eg: 0). In fact, the method would
> fail if the first item was the search item& it had an index of 0.
>
> So the code should be:
>
> function test5($workdata, $item2remove) {
> while($key = array_search($item2remove, $workdata)&& $key !==
> the difference between 47& 22 milliseconds isn't going to be
> noticeable.
>
> I myself have done some optimizations on code for stuff like this. But,
> it's pointless really. Focus on the bigger gains, not the little tiny
> ones. Remove most of the bigger bottlenecks& you'll notice the
Mike Cochrane:
But it also fails on way more edge cases...
I've been fiddling with that testcase, and it's interesting doing things
like moving the char to remove to 'z', and then working on
$workdata = array_fill(0,100,'z');
(which breaks two of the testcases!)
I get pretty random results, and I note that some of the algorithms are
modifying the copy of the array in the function scope, and some are
making a new array of everything else - I don't think any of these
results are statistically worth drawing conclusions on. We're also not
considering memory usage, for all these cases where we're building new
arrays rather than modifying the existing one.
This is how I'd prioritise things when considering algorithm choices:
* works for all inputs (having to put '//doesn't work on the last
element in the string' it *way* more important than microsecond efficiency)
* is immediately understandable and clear when reading the code (no
magic tricks)
* efficiency
--
Tim Oliver
t...@e2-media.co.nz
automatem
. software solutions |
|
|