I was building an asp site. So, I got into a feature that I can use either linq and foreach. What is about the eyesore? You’ll get it later.
Well, the feature that I wanted to make is to filter a list based on a criteria. Let’s just say that I had a big list of products. The filter would be “include item”, “exclude item”, and “I don’t care if that exist”. The filter was based on the product’s category.
First, I created a function that would receive all of the products. From that list, I created a smaller list that only contained all included items. I used linq to include them all! Simple and cost me a small amount of LOC. Then from that all included products, I removed all those that doesn’t included inside it.
Well, for once or twice it works fine. All sorted well. Then I met a process when I tested my small function. I tried to exclude all. What I got when I’m using linq is error. Error, error everywhere! Exceptions, exceptions everywhere! Of course I didn’t manage to catch it through. Why should I? I was testing, I wanted to know the location of possible exceptions first.
Well, that error confused me. Why? Even though I wrote linq in multiple lines, it treated as one error. Plus, I had to read a long linq statement – yes, it was so damn long about three lines with full width on screen. It gives me sore eyes! Hell! I read through out the error message, then linq, and repeat, and poof! I surrender.
Then I decided to take the linq that exclude the products into a foreach. Pheeew! I feel so glad when I can track the bug easily. What I got is the list got emptied by the time is still searching on the list. Or, some index were skipped just like that because I remove the element. Whoa! I realized that I was making a huge mistake there.
So, in the end, I created a temporary list that contains the same element as the included items list. But I was not just assign it and done. First I instantiate an empty temporary list, then I add all included items into it. Later on, I use foreach to search on the included items, but I delete the item on the temporary list.
It sounds so complex, why do I have to use foreach then a temporary list for such simple job? Why not includedList.RemoveAll(criteria)?
Because I need a good way to track things down. Also, I consider a good way to extend it in the future, so the method may be used by other class. Simple and easy to manage, debug, but cost more LOC, that’s using foreach. Well, you may say even more memories and more time. But using linq, it is hard to track things down.
I still recommend you to use linq anyway, it is a great way to get things done, but when you stuck up, use my suggestion and way then 🙂
I’ll post the code at about 12.00(GMT+7) so you could see the difference. Happy coding!
productList.RemoveAll(o => o.Fields["Category"].Value.Contains(criteria));
// it's just a short code, yes, but that criteria went so long and contains private data, I can't post it here.
productList = RemoveFromList(filter, productList);
private List<Item> RemoveFromList(string filter, List<Item> list)
List<Item> temp = new List<Item>();
temp.AddRange(list); // the temporary list
foreach (Item single in list) // I loop on the main list
foreach (Item child in single.Children)
if (!child.Name.StartsWith("xxx") && !child.Name.StartsWith("yyy")) // sorting criteria