I've been creating a system for storing objects that persist for a specified duration, then remove themselves. However, I'm having some trouble figuring out how to remove expired items from the array while the for loop is running (to minimize extra iterations through the array)
Here is what I've made so far. Terms in the list are flagged with a Boolean value indicating that they're done.
For i = 0 To VisualEffects.Count - 1 Step 1
VisualEffects(i).Update(gt)
VisualEffects(i).Draw(sb, Pos, Cam)
If VisualEffects(i).CD.isExpired() Then
VisualEffects.RemoveAt(i)
i = -1
End If
Next
Why does this produce an error? How can I remove a term from an array and continue iterating through the remainder of the loop?
Regards
Ares
The line
i = -1
sets i to -1, causing the For loop to terminate.
If you can, reverse the order of the loop so that you start with the last array element and count down. That makes the remove logic much more straightforward.
.NET arrays are fixed-size so you can't actually remove an element from an array at all. You can change the value of an element, so you can set an element to Nothing to remove the object that it referred to, but the element is still there. If you read the MSDN documentation for the Array class, you'll see that the RemoveAt method throws a NotSupportedException for this reason.
If you're actually using a collection rather than an array then you can call RemoveAt but you need to loop from the last index to the first rather than first to last. That way, removing an item will not affect the indexes of those items that you are yet to visit.
Related
I have an array to store true answers and false answer of random frame multiple choices questions:
var arraytruefalseanswer=[];
I use push method to insert every true and false answer in the array:
arraytruefalseanswer.push(trueanswer)
arraytruefalseanswer.push(falseanswer)
The problem is:
I can not remove the last element of arraytruefalseanswer .
Because
If I use pop method arraytruefalseanswer.pop(),
it will remove all elements in the array arraytruefalseanswer or bring back to
arraytruefalseanswer=[]
If i use delete, it is still leaving null.
Please help... how can I remove the last element of arraytruefalseanswer using flash AS3?
Thank you.
The documentation says: When you do a pop(), it returns items that were popped, and the array gets modified as a side effect. Therefore, in order to just remove the last element, you call arraytruefalseanswer.pop(); as is. You can use trace(arraytruefalseanswer) to verify if anything popped. Also check your code flow, it's possible that when you're popping your last element, you think the code reaches the call once but it's not so, and it say pops your entire array so you've left with an empty array. I can't say more without ever seeing your entire block of code where you work eith your truefalseanswer.
I'm trying so hard to initialize an array or arrayList of strings from a file while using a loop, but every function I'm using- put/enter/force nothing seems to work. the array time after time got filled with the last string I read even though I'm accessing a specific index that I increasing every iteration.
(I tried to add regular constant string and it worked well, I don't understand the difference.
Thanks to everyone who would help.
tArray:ARRAY[STRING] -- declaring
create tArray.make_empty
readingFile() --function
local
k:INTEGER_32
do
from k:=0
until curFile.end_of_file
loop
curFile.read_line
curLine:=curFile.last_string
tArray.force (curLine, k)
--tArray.put(curLine, k)
--tArray.enter (curLine, k)
--tArray.at (k):=curLine
--tArray.force ("sara", k+1)
k:=k+1
end
end
The feature read_line does not create a new string object every time, but rather reuses the last one. In other words, last_string always refers to the same object. The solution is to use a clone of the object associated with last_string at every iteration:
curLine := curFile.last_string.twin
I would like to remove a specific element from an array, not by index because the index value of that item is not static.
myarray.splice(myclip, 1);
When I use this code instead flash removes the first element in the array.
Is there something I am missing here?
Documentation of splice()
Both parameters need to be integers, the first one is the position of the element you want to delete, and the second one is the amount of elements you want to delete. Try myarray.splice(myarray.indexOf(myclip),1);
Don't know why it would only remove the first element in your snippet, maybe internally it casts myclip to 0? Doesn't matter, use indexOf. If that doesn't work, for loop through the array to get the position first.
I have this function where I use an array as a FIFO queue (i.e., put elements in it and process them using a first-in first-served approach). In particular, I call this array a MsgQueue as it holds messages.
The MsgQueue is used when a new msg is sent (event), which triggers the execution of the handleMsgSent() method, which I show next
function handleMsgSent(this, msg)
this.MsgQueue = [this.MsgQueue msg];
while(numel(this.MsgQueue) > 0)
m = this.MsgQueue(1);
this.MsgQueue = this.MsgQueue(2:end); % <----- OPTION A
% DO WHATEVER WITH THE MESSAGE
%this.MsgQueue(1) = []; % <------ OPTION B
end
end
As you can see I have marked the code with OPTION A and OPTION B comment. So, the point is option B ends up with the "Matrix Index is out of range for deletion" error while option A works (apparently) perfectly fine, with no errors.
Can anyone help me to understand the difference? Well, I understand that option A is not deleting anything but just "discarding" the first element of the array but, why does option B fails in deleting if there is at least one element in MsgQueue?
For an empty array, end is 0. If you check the documentation for the colon operator, for start>end it returns an empty array. Thus, the first option deletes noting in some cases while the second option always indexes the second element.
After debugging my code I seem to have realised of the reason. In my code there is a comment:
% DO WHATEVER WITH THE MESSAGE
The problem was that at this point I was invoking another method that triggered new messages to be sent and thus entering the handleMsgSent() method again. Thus, when I modify the MsgQueue before that I have no problems but when I do it afterwards I get into trouble.
I am facing some kind of a weird(as it appears to me) problem. I have a NodeList and need to remove an element from the NodeList while iterating through it. The NodeList has only one child element , so after removing that element that NodeList does not have any child element. Ideally the for loop should have stopped after removal of that element, but this is not happening and as the for loop runs for the second time, even when there are no child elements available, I am getting a NullPointerException.
Sample XML :
<Order OrderNo="1">
<Lines>
<Line LineNo="1"/>
</Lines>
</Order>
Sample Code :
NodeList nlLine = inDoc.getElementsByTagName("Line");
for(int cntLn = 0 ; cntLn < nlLine.getLength() ; cntLn++){
Element elLn = (Element) nlLine.item(cntLn);
if(//some condition){
elLn.getParentNode().removeChild(elLn);
cntLn--;
}
}
I am getting NullPointer exception on the linewhere i am getting the Parent Node and then removing the child. Any clue/lead/help on this?
You are decrementing the loop variable cntLn--.
I am pretty sure you meant to increment it cntLn++. And since you are already incrementing, just omit the line cntLn--;
TIP: As a healthy coding practice, always use the prefix increment operator ++cntLn in case of loops (unless you explicitly need the postfix behavior).
I think this behavior is caused by the last line of your loop (cntLn--;).
Assume, the list has one child, so you start your processing with cntln=0 and length=1 which means: execute the loop. Then you remove the node since the condition is evaluated to true and you decrease the counter to -1. After that your for-loop increases cntln again to 0 and you start again but now the node list of the Lines-element is empty!
Simply omit the last line and try again ;)
Nevertheless, I think this is a critical processing since you cannot foresee side-effects when removing nodes while looping over the node list. Maybe it would be better to store the index of each node to be removed in this loop and remove them later in another loop.
Let's see what your program does.
Getting Line nodes (nlLine)
Setting the cycle variable to 0, since it's bigger than nlLine's size (1), we are going in the cycle.
Supposing the condition is true
Removing a node from XML (nlLine not updated!)
decrement the cycle variable
Cycle variable is still 0 (because of step 5.) and the nlLine hasn't been updated so we are going in to the cycle again (0 < 1)
Since elLn did not have a parent at this time NPE will be thrown (it has been removed from the XML)
Solution: leave cntLn--; out from your code. You have to step to the next element of the nodelist, since elLn.getParentNode().removeChild(elLn); won't remove your actual node from the nodeList.
Tip: usually it's a bad practice to modify the list during for cycling over it. Although it's a bit different situation, but still try to avoid. You should do it AFTER the main loop. (e.g. create a removeThese list to store the elements you want to delete from the list you are looping, and you can remove them once you are done with the main loop. It's safe, it's easy to understand and easy to manage.)
Simply increment and not decrement cntLn by one when removing the child - the upper bound of the for loop is static, so your only chance to manage the state of the for loop is to modify the loop variable.