While developing an algorithm to match preferences to possibilities, I had to sort a generic list of a specific object type (SpecificObject). The first x objects would be matched, the rest would be excluded because of the number of available places. To determine the group of objects that would be matched and the group that would be excluded, I did something like this:

IEnumerable<SpecificObject> sortedObjects;
IEnumerable<SpecificObject> finalObjects;
IEnumerable<SpecificObject> exitObjects;

sortedObjects = from SpecificObject specificObject in AllSpecificObjects
                orderby specificObject.Ranking
                select specificObject;

finalObjects = sortedObjects.Take<SpecificObject>(numberOfPossibilities);
exitObjects = sortedObjects.Skip<SpecificObject>(numberOfPossibilities);

Next I would iterate through the possibilities and look for a match in (a subset of) the ‘finalObjects’ list. To be sure the matching would be done honestly during this process, I changed the value for the Ranking property after a positive match. This way, SpecificObjects that had no match yet would move up in the ranking and would be matched before SpecificObjects that already had one or more positive matches. Unfortunately, this had a very unwanted side-effect.

Can you think of it? Let me know and put it in the comments. The answer can be found in my next post.