Page 1 of 1

a function to remove a value from an array ?

Posted: Mon Sep 01, 2003 11:26 am
by VisionsOfCody
Hi
i've had a look at the list of functions starting with "array_" in the manual and didn't find a function that would enable me to completely remove a value from an array (using it's position) and then move up the following values to 'fill the gap', like this :

so my array is, for example,

$list=array("apple", "banana", "grape", "orange");

i'd like to be able to remove the value $list[1] and move up the next value "grape" to take its place

this must be possible - does anyone know the function to do it?

thanks

Posted: Mon Sep 01, 2003 11:34 am
by m3rajk
i don't know of a function, but it's not hard to write one....
let's seee... starteing at 12:34 pm my time

Code: Select all

function remove_array_element($array, $position){
  $array2=array();
  for($i=0;$i<$position;$i++){
    $array2[]=$array[$i];
  }
  for($i=($position+1);$i<(count($array)+1);$i++){
    $array2[]=$array[$i];
  }
  return $array2;
}

lordy!

Posted: Mon Sep 01, 2003 11:55 am
by VisionsOfCody
that was quick!
i was thinking i'd have to do something like that but it seemed a very daunting task - thank you :D

Posted: Mon Sep 01, 2003 1:51 pm
by JAM
Cant test as I'm at work, but if this works, it would be easier...

Code: Select all

// destroys a single element
unset ($list[1]);

ahaaaaa !!!

Posted: Mon Sep 01, 2003 2:24 pm
by VisionsOfCody
i'll give that a try - if it works then the world will be a brighter place
thanks :D

Posted: Mon Sep 01, 2003 2:32 pm
by VisionsOfCody
well, that seems to work ok for removing the element, but it leaves a hole in the array - so i'll be able to use m3rajk's solution to push everything over 1 position in the array.

nice work, thanks!

Posted: Mon Sep 01, 2003 2:47 pm
by m3rajk
that's exactly why i didn't suggest unset.

Posted: Mon Sep 01, 2003 2:49 pm
by JAM
m3rajk wrote:that's exactly why i didn't suggest unset.
Yah well, you really just cant tell what other people know now can you?

Posted: Mon Sep 01, 2003 3:21 pm
by m3rajk
true. unset is only meant to remove the value somehting is set at, since it can be used on a string or int, it would not make sens that it would bump things up.

i figured 2 for loops would be easier to follow than

Code: Select all

for($i=$place;$i<count($array);$i++){
  $array[$i]=$array[($i+1)];
}
unset($array[count($array)]);

Posted: Mon Sep 01, 2003 6:25 pm
by McGruff
How about a function which does just one thing ie resets keys in a numerical array?

It's better from a design point of view to give functions a single task. The advantage here is that now we have a little utility function which might have other uses (change an associative array to numerical for example). The $i arg also adds some flexibility so you can specify any integer for the first key.

Code: Select all

<?php
	
// reset array keys in sequence, $i is the first key
function resetNumericalKeys(&$array, $i)
{
	foreach($array as $value)
	{
		$array[$i] = $array[$value];
		$i++;
	}
}

// note passing by ref so, in use:
unset($array[$key]);
resetNumericalKeys($array, $i);
array_pop($array);


// We could stop right there but let's extend that further, to create a wrapper function which will delete any number of elements from a numerical array & reset the keys in sequence.
// "$keys" arg is an array of the keys to be deleted, $i the start key of the new array, as above
function unsetValuesResetKeys(&$array, $keys, $i)
{
	foreach($keys as $value)
	{
		unset($array[$value]);
		resetNumericalKeys($array, $i);
		array_pop($array); 
	}
}

// this may be slightly inefficient in the sense that ideally we'd have a setup where we reset array keys just once rather than once per loop. In practice it won't really matter.
?>
Note I didn't run this through the parser.

My aim here was to think a little outside the original problem and adapt the solution so that it can be applied to other similar problems without having to create more code. We end up with a utility fn possibly with other uses and a fn which will unset not just one but multiple elements. This particular example is kind of small beer really but it's a good principle to follow.

Posted: Mon Sep 01, 2003 7:49 pm
by volka
There are some built-ins that can restore the continuity of numerical indices, e.g.

Code: Select all

<?php
$arr = array(1,1,2,2);
unset($arr[1]);
$arr = array_values($arr);
print_r($arr);
?>
and hole or not foreach will work

Code: Select all

<?php
$arr = array(1,1,2,2);
unset($arr[1]);
foreach($arr as $val)
	echo $val, "\n";
?>

Posted: Mon Sep 01, 2003 8:05 pm
by McGruff
ah.. :oops:

Posted: Tue Sep 02, 2003 3:38 am
by VisionsOfCody
.... ah some interesting new stuff since yesterday - being a bit of a newbie, I'll have to examine McGruff's stuff in more detail before i can really grasp what's going - and Volka's solution seems pretty wicked - i'm off to try it right now !!

many thanks to all of you :D

Posted: Tue Sep 02, 2003 2:34 pm
by ChibiGuy
I had to do the same thing recently. This is how I solved the problem.

Code: Select all

unset($array[$offset]);
array_splice($array, 0);
// Now there is no more hole!