11.25.2009

Remove<T>(this IList<T> source, Func<T,bool> selector) why not?

Maybe I am just crazy, but it seems like removing or deleting items from a collection is always an after thought. Take IList for example, a list of items, with the ability to add and remove from it. We have a flurry of extension methods that are inherited from IEnumerable to add items but it seems like no one thought maybe it would be nice to beef up the remove method with some extension methods. Maybe I missed an extension namespace, maybe I am just crazy. How many times do we have to write the following bloated code just to remove something from a collection?

var ingredient = Ingredients.FirstOrDefault(i => i.FeedId == feed.Id);
Ingredients.Remove(ingredient);

Even worse, is when we want to remove multiple items from a list based on some criteria. I have to add a foreach loop of some sort to remove each item one at a time. Oh and, deal with the always wonderful: (System.InvalidOperationException: Collection was modified; enumeration operation may not execute). So, I have to remember to create a new list to avoid this dreadful mistake:

var ingredients = Ingredients.Where(i => i.FeedId == feed.Id).ToList();
foreach (var ingredient in Ingredients)
{
  Ingredients.Remove(ingredient);
}

Of course, now that I have created a new list, ToList(), I can simplify this to:

var ingredients = Ingredients.Where(i => i.FeedId == feed.Id).ToList();
ingredients.ForEach(i=> Ingredients.Remove(i));

But that is still icky, all that code just to remove an item or a set of items? So enough complaining on my part, it's time to put up or shut up. This is what I want to do in code:

Ingredients.Remove(i => i.FeedId == feed.Id);

Simple, right? And to do this here is the simple extension method:

public static void Remove<T>(this IList<T> source, Func<T, bool> selector)
{
  if (source == null || selector == null)
  {
    return;
  }

var itemsToRemove = source.Where(selector).ToList(); itemsToRemove.ForEach(i => source.Remove(i)); }

Now, I no longer have to worry about all these things when I want to remove items based on searching my list:

  • Doing a separate search for the items I want to remove
  • Creating a new list, avoiding the pitfall of enumerating when removing and getting "Collection was modified" exceptions.
  • Iterating over those items and calling remove on each

Some purists out there would be mad that I just quietly allow the source/selector to be null and not throw an exception. That's how I chose to implement this, if you want different behavior that's great. Just make sure you add this extension method to your arsenal! Maybe another RemoveSingle that throws an exception if it finds 0 or more than 1 item would be appropriate to add as well?

Happy coding!

11.13.2009

SyntaxHighlighter with Subtext/GWB

I've been very frustrated with the lack of flexibility with wordpress.com hosted blogs, so I am yet again moving. This time I wanted to host my own instance of Subtext but discovered that geekswithblogs.net uses Subtext and figured I would give one last attempt to a hosted community online :) I guess I just don't want to deal with running my own server just for a blog.

The most important thing I wanted back was Syntaxhighlighter which was about impossible to use with wordpress.com without paying or running my own instance. I figured I would share how other people can use Syntaxhighlighter with Subtext.

What is it? It is a great tool to bring your code samples to life with very little trouble. All you have to do is mark them with <pre> tags and it does the rest. It supports pretty much any language you want to use and can be extended for others.

Steps to integrate with Subtext/GWB

  1. Pick a theme, I prefer the RDark theme.
  2. Modify Custom CSS under Options->Configure
    1. Add these css imports.

      @import url("http://alexgorbatchev.com/pub/sh/current/styles/shCore.css"); @import url("http://alexgorbatchev.com/pub/sh/current/styles/shThemeRDark.css");
    2. Note: If you want a theme besides RDark, set that instead.
    3. Note: I have this setup to use the current version of SyntaxHighlighter, if you need an old version replace current in the url with the version.
  3. Modify Static News/Announcement in Options->Configure, if you have a SubText install you are hosting and you have the option for Sitewide Tracking code, you can use that as well.

    1. This is where you can insert the javascript needed to perform the highlighting.
    2. Include the shCore.js

         <script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js"></script&gt; 
        
    3. Include any brushes, I have c#,python,javascript and css included here:

          <script type="text/javascript" language="javascript"    src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js"></script&gt;
          <script type="text/javascript" language="javascript"    src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js"></script&gt;
          <script type="text/javascript" language="javascript"    src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js"></script&gt;
          <script type="text/javascript" language="javascript"    src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js"></script&gt;
        
    4. Enable highlighting

        <script>
          SyntaxHighlighter.all();
        </script>
        
  4. See this link for how to use it.
    1. Huge Fail: FCKEditor, at least the version used here on GWB puts <br> tags in <pre> tags, stupid idiots, and it strips formatting so until this is fixed this will be a major pain, in the mean time I am using Windows Live Writer and I have the HTML formatting option set (turn off XHTML formatting or it will reformat pres).

10.22.2009

Apply DeMorgan's law refactoring

After reading up on some refactorings after a few hours of refactoring today, I thought it might be nice to share this refactoring with everyone.

I ran into some code today, a simple equality comparison method, except it was comparing about 7 properties, so even worse than this:

public bool Compare(item x, item y)
{
  return !(x.a != y.a || x.b != y.b || x.c != y.c);
}
Even though it doesn't take long to figure out what it is doing, it takes more time to figure out than if we applied DeMorgan's law in what is known as avoiding double negatives refactoring:

public bool Compare(item x, item y)
{
  return x.a == y.a && x.b == y.b && x.c == y.c;
}
Any time you run across code where you negate a set of conditions, do everyone else a favor and invert the conditions. Apply DeMorgan's law to make the code more readable. To freshen up on the rules, visit http://en.wikipedia.org/wiki/De_Morgan's_laws. Saving even 30 seconds of translation every time someone looks at that line of code, becomes a huge savings.

10.5.2009

OrderBy().Descending()

Just wanted to share a quick extension method, it's really simple yes but it's power is in reducing lines of code. If you have ever wanted to apply an order by clause to a collection of items and conditionally do this based on a direction, you know that the only choices available are different methods OrderBy and OrderByDescending. It really is too bad because the internal OrderedEnumerable has a boolean flag for direction that would have been nice as a parameter, but better yet why not make it fluent while we are at it!

Normally we might have to write code like this, assuming I want to order by a particular key in a dictionary field on the item record. (This is just a sample of a nasty selector for ordering that we wouldn't want to be copy & pasting):

if(ascending)
{
  items = items.OrderBy(i => i.DictionaryField.Keys.Contains(key) ? i.DictionaryField[key] : null)
}
else
{
  items = items.OrderByDescending(i => i.DictionaryField.Keys.Contains(key) ? i.DictionaryField[key] : null)
}
The next refactoring might be, which might not be so bad if we could use var instead of Func..., but c# doesn't deal well with implicit functions because of the static typing thing!

Func<Item, object> nastySelector = i => i.DictionaryField.Keys.Contains(key) ? i.DictionaryField[key] : null;
if(ascending)
{
  items = items.OrderBy(nastySelector);
}
else
{
  items = items.OrderByDescending(nastySelector);
}
Next, I can combine the if/else using the ternary operator:

Func<Item, object> nastySelector = i => i.DictionaryField.Keys.Contains(key) ? i.DictionaryField[key] : null;
items = ascending ? items.OrderBy(nastySelector) : items.OrderByDescending(nastySelector);
This is pretty good, but it's not very readable. A chained Descending method (on OrderBy results) would be nice, ridding us of the Func declaration garble and even making our items assignment much more fluent!

ordered = items.OrderBy(i => i.DictionaryField.Keys.Contains(key) ? i.DictionaryField[key] : null);
items = ascending ? ordered : ordered.Descending();
So here is the Descending implementation, this is for Enumerable lists only, if you have an IQueryable collection, cast it to IEnumerable first. This makes use of reflection to set the internal field (descending) on the internal class that you are eternally not supposed to touch :).

public static IOrderedEnumerable<TSource> Descending<TSource>(this IOrderedEnumerable<TSource> source)
{
  var field = source.GetType().GetField("descending", BindingFlags.NonPublic | BindingFlags.Instance);
  if(field == null)
  {
    throw new ArgumentException("Source must be OrderedEnumerable");
  }

field.SetValue(source, true);

return source; }

10.2.2009

ForEach or ForEachCopyIntoNewList?

All of us have desired a ForEach extension method in .Net for a while now, after being spoiled with all the new syntactic sugar with lambdas and linq in c#. We've no doubt all implemented our own, here is the one I use:

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
  foreach (var item in source)
  {
    action(item);
  }
}
My only issue with this and the foreach loop itself, is that you cannot modify the original collection with your action. There are plenty of cases where we only have a Remove method on a collection and would like to have a RemoveAll. To get around this issue, we can copy items into a new list and iterate over it. With this we can even remove items from the original collection! However, I am now wondering if this should be the default behavior of a ForEach extension method:

public static void ForEachCopyIntoNewList<T>(this IEnumerable<T> source, Action<T> action)
{
  var items = source.ToList();
  items.ForEach(action);
}
I am wondering what everyone thinks, obviously this has implications for delayed execution / lazy loaded scenarios but with that aside, thoughts? I am also looking for a good name to keep this as an alternative extension method but ForEachCopyIntoNewList is rather icky, so if you have a suggestion please let me know.