Jump to content

[SOLVED] Removing an element from an array without leaving a hole in the index sequence


Errant_Shadow

Recommended Posts

As my title suggests, I'm removing an element in an array, but what's happening is that it's leaving a hole in the index sequence.

 

I start with something like...

$myArray = array("dog", "fish", "cat");

 

then I remove index number 1 ("fish") with unset...

unset($myArray[1]);

 

but it leaves the keys in tact, returning

.[0] => "dog"

.[2] => "cat"

 

what I need it to do is return:

.[0] => "dog"

.[1] => "cat"

 

because if I were to, say, use a for() loop to increment through the array, it would return an error when it got to index 1, since it doesn't exist, and since the last index of the array is now 1 number higher than it should be, the for() loop won't even check it; it'll hit the end of the loop before the index variable is high enough.

 

I've read through a lot of array documentation in the PHP manual, but I've found nothing that's worked so far... any advice on this one?

 

 

Link to comment
Share on other sites

<?php
$myArray = array("dog", "fish", "cat");
unset($myArray[1]);
$myArray =array_values($myArray);
?>

 

 

EDIT:

may i also suggest you look at foreach

 

ie

<?php
$myArray = array("dog", "fish", "cat");
unset($myArray[1]);
foreach($myArray as $A)
{
echo "$A<br>/n";
}
?>

 

Link to comment
Share on other sites

What I'm doing is setting a few multidimensional arrays from mysql and using the data in a browser game. So when the game calls for it, I need to remove certain elements, such as NPC competitors from those arrays as I process them over and over.

 

... would it work to use next() last() and current() in lieu of a traditional for() loop?

 

something like...

 

<?php
// for a given array
$myArray = array(1, 2 ... "n");

// find the value of the last element in the array
$endof_myArray = end($myArray);

// then reset the pointer, checking to make sure the current index does not point to the end,
// and moving the pointer ahead by one for each successive loop...
for (reset($myArray); current($myArray) != $endof_myArray; next($myArray) {
// do some stuff...
if (current($myArray) != "foobar") {
	current($myArray) = "foobar"
} // end if ()
} // end for ()
?>

Link to comment
Share on other sites

Actually, array_values() worked perfectly. I looked at that in the manual, but I had already read through almost everything else and I just skimmed it; never clicked with me to try it -_-

 

Thank you very much for you help, MadTechie, I really appreciate it.

Link to comment
Share on other sites

On one last note:

 

on my method using reset(), current(), and next(). It -will- work, -but- my initial method was flawed.

 

<?php
// here, $r represents the current index in $racerArray

// first, I set up an $endof... variable to use in my loop, and then reset the internal pointer
$endof_racerArray_this_damage = end($racerArray[$r]['damage']);
reset($racerArray[$r]['damage']);

// now, using my array as the first arguement of the for() loop,
// as long as the current pointer is not set to the end of the array (using our $endof... variable),
// I move the pointer to the next index for each successive loop...
for ($racerArray[$r]['damage']; current($racerArray[$r]['damage']) != $endof_racerArray_this_damage; next($racerArray[$r]['damage'])) {

// unlike array_walk(), you can easily and directly modify your array's values
// and even access external arrays and use other variables inside the loop

// but this is an important part...
// if at any time inside this loop you create some criteria that would disturb the loop,
// for instance, such as destroying the array with unset(), or otherwise create an invalid
// argument, you -must- break the loop manually, so be careful
if ($stuff == "happening") {

	break;

} // end if()

} // end for ( ... )

?>

Link to comment
Share on other sites

Okay i'm not sure but are you trying to do something like this

 

<?php
$racerArray = array(
			array("Name" => "Errant", "damage" => 0, "cheat" => false),
			array("Name" => "Shadow", "damage" => 0, "cheat" => false),
			array("Name" => "MadTechie", "damage" => 0, "cheat" => true)
			);

$stillraceing = true;
ob_start();
while($stillraceing)
{
foreach($racerArray as $RacerKey => $Racer)
{
	$stillraceing = (count($racerArray) > 1); //race until last person
	if(!$stillraceing) break;
	//take damage
	$damage = (rand(1,10) * rand(1,10));
	$racerArray[$RacerKey]['damage'] = ((!$Racer['cheat']))?$Racer['damage'] + $damage:$Racer['damage'];
	echo $Racer['Name']." Take $damage damage, ".(100-$racerArray[$RacerKey]['damage'])." Remaining<br>\n";

	//remove them
	if($racerArray[$RacerKey]['damage'] >= 100)
	{
		echo $Racer['Name']." is out of the race<br>\n";
		unset($racerArray[$RacerKey]);
	}
	flush();
	ob_flush();
}
}
$winner = current($racerArray);
echo $winner['Name']." Wins";
?>

 

PS: i always win ;)

 

EDIT: updated the damage message

Link to comment
Share on other sites

*nods* I think so. I'll research foreach() some time in this coming week and I suspect I'll implement it.

 

My usual programming methods are to find some convoluted, overly complicated way to do something, then find out there's an easier way and re-write my code to use that ><

 

On the plus side, once I find that easier method, I'm slow to forget it

 

What does flush() and ob_flush() do here?

Link to comment
Share on other sites

flush and ob_flush()

basically dump all the last echos to apache to output to the browser,,

 

if you run the code, without them, then run it again with them, your notice that without them it delays for a second or 2 and them dumps everything to screen, while with them it dumps them part at a time..

 

hope that makes sense,

Link to comment
Share on other sites

Think of it this way

<?php
echo "Hello ";
sleep(5);
echo "World";
?>

this will display

Hello World
in just over 5 seconds

<?php
on_start();
echo "Hello ";
ob_flush();
flush();
sleep(5);
echo "World";
?>

this will display

Hello
then display 5 seconds later display
World

the final result is still

Hello World
but the flush means you didn't have to wait for the script to end
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.