How come there is no straight-foward obvious way to simply remove a given
value from an array?
Just look at the number of horrible ways people solve this obvious problem:
http://stackoverflow.com/questions/7225070/php-array-delete-by-value-not-key
Shouldn't we have something simple, like:
array_remove($array, $value) : array (returns a new array)
and/or
array_delete(&$array, $value) : bool (modifies array directly)
?
Hi!
How come there is no straight-foward obvious way to simply remove a given
value from an array?
The same reason there's no simple way to undefine variable whose value
is 42 without knowing the variable name. Array is a container indexed by
keys, not values. So if you've got just a value, there's no way to know
if it's in the container at all, and if it is, where it is, except for
going through all the values and checking if any of them is equal to
what you nedd.
Just look at the number of horrible ways people solve this obvious problem:
I see:
if(($key = array_search($del_val, $messages)) !== false) {
unset($messages[$key]);
}
Nothing horrible here.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
I like that chose 42 for the value. You win, and I completely agree.
On Wed, Aug 15, 2012 at 4:22 PM, Stas Malyshev smalyshev@sugarcrm.comwrote:
Hi!
How come there is no straight-foward obvious way to simply remove a given
value from an array?The same reason there's no simple way to undefine variable whose value
is 42 without knowing the variable name. Array is a container indexed by
keys, not values. So if you've got just a value, there's no way to know
if it's in the container at all, and if it is, where it is, except for
going through all the values and checking if any of them is equal to
what you nedd.Just look at the number of horrible ways people solve this obvious
problem:I see:
if(($key = array_search($del_val, $messages)) !== false) {
unset($messages[$key]);
}Nothing horrible here.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Hi!
How come there is no straight-foward obvious way to simply remove a given
value from an array?The same reason there's no simple way to undefine variable whose value
is 42 without knowing the variable name. Array is a container indexed by
keys, not values. So if you've got just a value, there's no way to know
if it's in the container at all, and if it is, where it is, except for
going through all the values and checking if any of them is equal to
what you nedd.Just look at the number of horrible ways people solve this obvious problem:
I see:
if(($key = array_search($del_val, $messages)) !== false) {
unset($messages[$key]);
}Nothing horrible here.
In addition to that, one should be aware that a value can exist
multiple times in an array, whereas keys are unique. So there are
infinitely many possible deletion strategies.
Btw, deleting all values (not just the first) is also very easy currently:
foreach (array_keys($array, $delValue) as $key) {
unset($array[$key]);
}
Btw, deleting all values (not just the first) is also very easy currently:
foreach (array_keys($array, $delValue) as $key) {
unset($array[$key]);
}
Even easier still, just do this:
$array_var = array();
--Kris
Btw, deleting all values (not just the first) is also very easy currently:
foreach (array_keys($array, $delValue) as $key) {
unset($array[$key]);
}Even easier still, just do this:
$array_var = array();
It's often overlooked, but array_keys has a second parameter that only
returns the keys for a certain value: http://php.net/array_keys ;) So
no, that does not clean off the whole array.
Nikita
Btw, deleting all values (not just the first) is also very easy
currently:foreach (array_keys($array, $delValue) as $key) {
unset($array[$key]);
}Even easier still, just do this:
$array_var = array();
It's often overlooked, but array_keys has a second parameter that only
returns the keys for a certain value: http://php.net/array_keys ;) So
no, that does not clean off the whole array.Nikita
If you re-initialize it by setting it to array(), then yes that most
definitely will clear all the values in the array. As far as I know,
array_keys()
has nothing to do with that.
--Kris
On Wed, Aug 15, 2012 at 1:31 PM, Nikita Popov nikita.ppv@gmail.comwrote:
On Wed, Aug 15, 2012 at 10:29 PM, Kris Craig kris.craig@gmail.com
wrote:Btw, deleting all values (not just the first) is also very easy
currently:foreach (array_keys($array, $delValue) as $key) {
unset($array[$key]);
}Even easier still, just do this:
$array_var = array();
It's often overlooked, but array_keys has a second parameter that only
returns the keys for a certain value: http://php.net/array_keys ;) So
no, that does not clean off the whole array.Nikita
If you re-initialize it by setting it to array(), then yes that most
definitely will clear all the values in the array. As far as I know,
array_keys()
has nothing to do with that.--Kris
Err nevermind, I think I misread what you were trying to do. If you want
to only clear a certain value, then yes using array_keys()
with a search
value specified is the way to go. If you want to clear all values in the
array period (which is what I thought you were saying), then
re-initializing with array() makes the most sense.
--Kris
Am 15.08.2012 22:22, schrieb Stas Malyshev:
Just look at the number of horrible ways people solve this obvious problem:
I see:
if(($key = array_search($del_val, $messages)) !== false) {
unset($messages[$key]);
}Nothing horrible here.
One thing that should be noted in this case and any solution that relies
on unset() is that even though its simple and fast, it will not result
in a properly indexed array. The same goes for any array_diff based
solution.
I tried and compared the following solutions and ordered them according
to their performance. The fastest (and with a correct result) solution
is based on array_slice. Why this is the case I can not say...I am not
arguing for another array-function (as there are so many already)...but
I certainly have my own array_remove implementation, since it's such a
common use-case.
function array_remove_slice(&$haystack,$needle){
while ( true ) {
$pos = array_search($needle,$haystack,true);
if ( $pos === false ) return;
$haystack = array_merge(
array_slice($haystack,0,$pos) ,
array_slice($haystack,$pos+1)
);
}
}
/* ~1.5 times slower than slice */
function array_remove_unset(&$haystack,$needle){
while ( true ) {
$pos = array_search($needle,$haystack,true);
if ( $pos === false ) break;
unset($haystack[$pos]);
}
}
/* ~2.3 times slower than slice */
function array_remove_loop(&$haystack,$needle){
$result = array();
foreach( $haystack as $value ) {
if ( $needle == $value ) continue;
$result[] = $value;
}
$haystack = $result;
}
/* ~3.5 times slower than slice */
function array_remove_diff(&$haystack,$needle){
$haystack = array_diff($haystack,array($needle));
}
How come there is no straight-foward obvious way to simply remove a given
value from an array?
Well, this sounds like a reason for creating SplSet class
How come there is no straight-foward obvious way to simply remove a given
value from an array?Well, this sounds like a reason for creating SplSet class
There's already SplObjectStorage which CAN act like a Set for objects
only. It's a terrible solution in my opinion and am working on
creating a proper one. I don't know if that effort will be accepted,
but I wanted to point out that a set already exists in the SPL.
I think adding more collection-types is the intuitive reaction to this
issue, but there's something to be said for the idea of having only a
single collection-type - I think that's one PHP feature we should not give
up.
Not having to pick and choose (and compromise) to select the "right"
collection-type, and not having to refactor when you realize you needed
another collection-type - as well as easy comprehension for developers...
these are valuable aspects of having only a single collection-type. Some
newer languages like Opa embrace that idea with great elegance. Giving up
on that idea should be the last option, in my opinion.
There are plenty of cases for collections of objects that do not have a
scalar key, where the key is indeterminate, or where the key can change -
and thus cannot have known indexes.
As an aside note, I recently benchmarked array_search()
for a project that
needs to store many different types of objects in a list - and searching a
list with 1000 objects for one specific object is extremely fast: a couple
of micro-seconds more (per search) when compared against a hash-based
lookup with a known key, so (in my case) nothing to worry about at all in
terms of performance.
Arrays are a powerful and pure feature in PHP - I would vote against
introducing more collection-types, and instead leverage the already
powerful and well-understood existing singular collection-type.
On Sat, Aug 18, 2012 at 2:42 AM, Alexey Zakhlestin indeyets@gmail.comwrote:
How come there is no straight-foward obvious way to simply remove a given
value from an array?Well, this sounds like a reason for creating SplSet class
Hi,
2012/8/16 Rasmus Schultz rasmus@mindplay.dk:
How come there is no straight-foward obvious way to simply remove a given
value from an array?Just look at the number of horrible ways people solve this obvious problem:
http://stackoverflow.com/questions/7225070/php-array-delete-by-value-not-key
Shouldn't we have something simple, like:
array_remove($array, $value) : array (returns a new array)
and/or
array_delete(&$array, $value) : bool (modifies array directly)
?
It was amazing that this thread has close to 90 mails.
I've added some use cases of array_udelete() to wiki, since
some people fails to see how it could be useful. I also bring
back to array_walk()
version of equivalent example. I just
don't see any reason why we should replace it with slower
foreach() version.
I think the RFC page is almost complete.
https://wiki.php.net/rfc/array_delete
Any more comments?
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi,
2012/8/16 Rasmus Schultz rasmus@mindplay.dk:
How come there is no straight-foward obvious way to simply remove a given
value from an array?Just look at the number of horrible ways people solve this obvious problem:
http://stackoverflow.com/questions/7225070/php-array-delete-by-value-not-key
Shouldn't we have something simple, like:
array_remove($array, $value) : array (returns a new array)
and/or
array_delete(&$array, $value) : bool (modifies array directly)
?
It was amazing that this thread has close to 90 mails.
I've added some use cases of array_udelete() to wiki, since
some people fails to see how it could be useful. I also bring
back toarray_walk()
version of equivalent example. I just
don't see any reason why we should replace it with slower
foreach() version.I think the RFC page is almost complete.
https://wiki.php.net/rfc/array_delete
Any more comments?
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Take a look at:
http://php.net/manual/en/function.array-walk.php#refsect1-function.array-walk-parameters
Look at funcname parameter. Notice:
Only the values of the array may potentially be changed; its structure cannot be altered, i.e., the programmer cannot add, unset or reorder elements. If the callback does not respect this requirement, the behavior of this function is undefined, and unpredictable.
I'm just going to change the behavior back when you switch it to
array_walk. It's less clear and technically undefined.
Hi,
2012/8/22 Levi Morrison morrison.levi@gmail.com:
Hi,
2012/8/16 Rasmus Schultz rasmus@mindplay.dk:
How come there is no straight-foward obvious way to simply remove a given
value from an array?Just look at the number of horrible ways people solve this obvious problem:
http://stackoverflow.com/questions/7225070/php-array-delete-by-value-not-key
Shouldn't we have something simple, like:
array_remove($array, $value) : array (returns a new array)
and/or
array_delete(&$array, $value) : bool (modifies array directly)
?
It was amazing that this thread has close to 90 mails.
I've added some use cases of array_udelete() to wiki, since
some people fails to see how it could be useful. I also bring
back toarray_walk()
version of equivalent example. I just
don't see any reason why we should replace it with slower
foreach() version.I think the RFC page is almost complete.
https://wiki.php.net/rfc/array_delete
Any more comments?
--
Yasuo Ohgaki
yohgaki@ohgaki.netTake a look at:
http://php.net/manual/en/function.array-walk.php#refsect1-function.array-walk-parametersLook at funcname parameter. Notice:
Only the values of the array may potentially be changed; its structure cannot be altered, i.e., the programmer cannot add, unset or reorder elements. If the callback does not respect this requirement, the behavior of this function is undefined, and unpredictable.
I'm just going to change the behavior back when you switch it to
array_walk. It's less clear and technically undefined.
Ok, then my commit to the doc was outstanding still.
Old PHP was behaved badly with reference variables.
I'll remove obsolete statement.
I'll fix it later.
Thank you.
--
Yasuo Ohgaki
yohgaki@ohgaki.net