for (Iterator it = container.iterator(); it.hasNext(); )
if (!predicate(it.next())(
it.remove();
It's more ugly and error prone if you've got to juggle an index, though. for (i = ctr_size(container); i > 0; i--)
if (!predicate(container, i - 1))
ctr_remove(container, i - 1); for (i = ctr_size(container); i--; )
if (!predicate(container, i))
ctr_remove(container, i); filter predicate xs
:)I always love the problems on SPOJ where they give you the number of cases up front, because in Haskell you can almost always throw out that value. Your map function knows when the list is out of elements.
CollectionUtils.filter(collection, predicate);
Of course aside from being a bit more verbose, predicate needs to be an object (often a singleton), because you can't pass around functions.var filteredCollection = collection.Where(x => predicate(x));
var filteredCollection = collection.Where(predicate);
I agree that C# is a fundamentally usable language. for (i = container.size; i-->0;)
if(deletep(container, i))
container.remove(i); while(container.Size > 0)
container.Remove(0);
No need for variables. container.clear();
No need for looping :)The iterator may become invalid if the collection it derived from changes.
Iterator delete methods are crazy to begin with since iteration does not correlate with deletion. But anyway it is not clear where the iterator's cursor will point after you delete the current element. You could end up deleting every second element in the container.
In the systems class I TAed, when students had memory corruption problems, removing items while iterating over a linked list was at the top of my list of things to look for.
But thats not the point - while (not empty) is not iterating over the loop, so there is no danger of corrupting the iterator.
while(collection.Count > 0)
{
collection.Delete(0);
}
.. which is a working implementation of clear, though probably superfluous.and...
int i = 0;
while(i < collection.Count)
{
collection.Delete(i);
i++;
}
which does try to walk along the list and is broken.Also, .Net has a specific exception to stop you modifying a collection while an enumerator is walking along it. Google for "Collection was modified; enumeration operation may not execute"
for (int i=0,j=this.MyControl.TabPages.Count; i < j; i++) {
this.MyControl.TabPages.Remove(this.MyControl.TabPages[i]);
}for (int i=this.MyControl.TabPages.Count - 1; i > 0; i--) { this.MyControl.TabPages.Remove(this.MyControl.TabPages[i]); }
Imagine the count is 2. The first iteration you delete item 1, the second you delete item 0, and then the loop exits.
EDIT: Actually, as someone else pointed out, it's clearer to use a while loop that deletes the 0th item until the collection is empty.
I think what you meant was:
for (int i=this.MyControl.TabPages.Count; i > 0; i--) { this.MyControl.TabPages.Remove(this.MyControl.TabPages[i-1]); }
for (int i=this.MyControl.TabPages.Count - 1; i >= 0; i--) {
this.MyControl.TabPages.Remove(this.MyControl.TabPages[i]);
}
Though a simple while loop is much easier to follow, even if its less efficient than removing the elements in reverse.while (MyControl.TabPages.Count > 0) { MyControl.TabPages.RemoveAt(MyControl.TabPages.Count-1); }
For loop are nothing more than while loops with:
(1) an assignment (int i = MyControl.TabPages.Count in this case)
(2) an extra command (i-- in this case) added to the end
Regarding for vs while, I find the choice is important only in the intent they emphasize: while puts emphasis on the condition, whereas for puts the emphasis on the iteration. I think in this case the condition (that the list is not empty) is deserves more emphasis than the iteration through the elements of said list - hence why I find the while version to be more readable. YMMV and all that :)
Ten years ago, sure, but nowadays I trust the compiler to do this for me ;-)
It's TFA's method, except broken (or not fixed, word it as you prefer).
For you case deleting from either end ought to be fine, but you've made the other implicit tradeoff because merely accessing items in the middle of a linked list will be slow. In the case of something like a JavaScript array, removing from the front is 80% slower than removing from the end:
Same deal with Python lists. From the Python spec:
http://docs.python.org/tutorial/datastructures.html#using-li...
It is also possible to use a list as a queue, where the first element added is the first element retrieved (“first-in, first-out”); however, lists are not efficient for this purpose. While appends and pops from the end of list are fast, doing inserts or pops from the beginning of a list is slow (because all of the other elements have to be shifted by one).
But, honestly, for the majority of stuff in Javascript, I'd be surprised if some kind of hybrid hash-map / ordered skip list weren't being used instead. Ordered skip lists can be about as fast as a binary tree, without the costs associated with rebalancing, and a lot less complexity. You'd have some tradeoffs in memory usage depending on how you want to tune your skip list, but given the absurd memory requirements for modern software, that doesn't seem to be a consideration amongst programmers anymore.
So ... I accept that removing items from the head of a list in these higher-level languages is (a lot) more expensive. But I still don't get why.
One way is to leave the indexes intact and keep an offset around, so you may map the nth logical index to the nth physical one. (Add 1 on a shift, subtract 1 on an unshift.)
But if you wanted this behaviour, there are more efficient ways: http://en.wikipedia.org/wiki/Circular_buffer
So in the common case, you are in fact looking at a big memcpy every time you remove an object from the front, unless you do some magic with keeping track of a nonzero offset in your C array. V8 does that magic in some cases but not others, as far as I can tell.
Parent has a point for arrays/arraylists, though, you need to copy everything after the element.
If you recalculate it right there, you've actually done nothing in terms of the algorithmic complexity. If you defer it either until it's needed or until you next enumerate the list, then you get to O(1) in the case of individual removes at the end (as long as they're interspersed with other operations), but you're still O(n^2) for removing the entire list starting at the tail.
In terms of performance, another consideration may be important here: invalidation and redrawing of the UI. Controls like tab pages may update the UI for every modification of the tab collection (unless updates have been suspended). Removing from the end will look slightly more pleasant than removal from the start in this case.