Recently on my project I faced a task that could be simplified to a following problem:
I have a list of objects of class Foo, which has a field bar which is a String. I get a list of Strings X and the task is:
a) from the set of objects Foo I need to filter out anything for which the bar field is not equal to one of the Strings on the list X
b) the order of objects Foo according to their bar value must match the order of Strings on the list X
Google Collections came to the rescue allowing me to write a nice and concise (and bug-free!) code in a matter of minutes. Here is how it looked like:
import java.util.Collection;
import java.util.List;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Ordering;
public class Bazz {
private final static class Foo {
private String bar;
public String getBar() {
return bar;
}
}
/**
* @param bars
* Reference bar List to define filter and sorting
* @param foos
* List of object that needs to be filtered and sorted
* @return Filtered and sorted Foos
*/
public ListfilterAndSort(final List bars, final List foos) {
Collectionfiltered = Collections2.filter(foos, new Predicate () {
public boolean apply(Foo foo) {
return bars.contains(foo.getBar());
}
});
OrderingfooOrdering = Ordering.explicit(bars).onResultOf(new Function () {
public String apply(Foo foo) {
return foo.getBar();
}
});
return fooOrdering.sortedCopy(filtered);
}
}
The only thing I'm currently wondering about is how would it look in a functional language like Scala for which the book is already in the reading queue...
For comparison the c# version is:
ReplyDeletefoos.Select(f=>bars.Constains(f.getBar())).OrderBy(f=>f.GetBar())
and that comes with standard library.
Scala version:
ReplyDeletefoos.filter(bars.contains).sort(_.bar < _.bar)
Obviously you can make it more verbose (and comprehensible):
foos.filter(bars.contains(_)).sort((x,y :Int) => x.bar < y.bar)