Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Depends on what you want to accomplish and what your container and iterators support. If your Iterator offers a delete method, I think it's a very elegant and clear way to filter a container.

  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.


Even with plain C, you can just iterate backwards:

    for (i = ctr_size(container); i > 0; i--)
        if (!predicate(container, i - 1))
            ctr_remove(container, i - 1);


Use the goes-to-zero operator.

  for (i = container.size; i-->0;)
    if(deletep(container, i))
      container.remove(i);


Reminds me of something :)


    for (i = ctr_size(container); i--; )
        if (!predicate(container, i))
            ctr_remove(container, i);


That's arguably better. Nitpick: start at ctr_size(container) - 1. [Feel free to edit your post, and I'll just delete this one.]


Nope. The decrement is occurring in the test, so it occurs after the initialization and before the first iteration.


  filter predicate xs
:)


Haskell, I assume. Two things really make Haskell shine when it comes to problems like this: 1) higher-order list operations -- you're not iterating through indices, so there is no possibility for off-by-one errors, and 2) immutability -- your code takes a new list with the undesirable elements removed; you can't remove elements of a structure at the same time you're iterating through it.

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.


Yeah, I was thinking Haskell, but any functional language will do. Problems like the one in the blog post really make you appreciate them.


The snippet I posted can easily be made into a generic function<T> that takes a collection<T> and a predicate<T>. For example, the Apache Commons library offers such a function for Java, so where available the code comes down to the fairly similar

  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.


It's not as concise as Haskell, but the addition of FP capabilities to C# make it a lot more pleasant as a practical language than it was in earlier days.

var filteredCollection = collection.Where(x => predicate(x));


As far as I remember you can write that as

  var filteredCollection = collection.Where(predicate);
I agree that C# is a fundamentally usable language.


l = [i for i in l if predicate(i)]


  while(container.Size > 0)
    container.Remove(0);
No need for variables.


  container.clear();
No need for looping :)


Yeah sure, :) , but I meant for those other cases when there are no Clear() method. :)


The correct idiom is delete list head until list is empty.

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.


My example wasn't clearing the list, it's a filter. And depending on what language and library you're talking about, it's very clear where the cursor will point to after a delete. There's nothing crazy about it with an even halfway sane collection framework.


Discussion about iterators removing anything aside, I don't think your example disagrees with the parents point. His point was that iterating over a containing while removing items should raise red flags. And it should, always. You should always inspect such loops with more scrutiny because more things are going on, and it's surprisingly easy to get such code correct as multiple things are changing out from under you.

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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: