views:

47

answers:

2

I have a class like this

public class HistoryEntry
{
    DateTime Date{ get; protected set; }
    HistoryType EntryType { get; protected set; }
}

public enum HistoryType
{
    Cancelled,
    Cleared,
    Redeemed,
    Refunded
}

I have an unordered list of these History Entries, and I do Exists statements to see if an entry exists in the list.

return Entries.Exists(e => e.EntryType == HistoryEntryType.Cancelled);

Now I need to change this so that this method returns whether or not a Cancelled entry exists after the TimeStamp of the last Cleared entry if one exists, otherwise just return whether a Cancelled entry exists at all.

I'm limited to options available in .Net 2.0

A: 

Search for the index of the matching entries in the list, which requires two searches.

int p = Entries.FindIndex(e => e.EntryType == HistoryEntryType.Cleared);
if (p < 0)
    p = 0;
p = Entries.FindIndex(p, e => e.EntryType == HistoryEntryType.Cancelled);
return (p >= 0);

See http://msdn.microsoft.com/en-us/library/efasdh0s.aspx.

Loadmaster
Doesn't that assume the list is in descending order by the DateTime property?
Brandon
Yes. The original post was not clear about how the list was ordered.
Loadmaster
+1  A: 

How about something like this:

    private bool ContainsCanceled(List<HistoryEntry> list)
    {
        list.Sort();
        int index = list.FindLastIndex(delegate(HistoryEntry h) { return h.HistoryType == HistoryType.Cleared; });
        for (int i = index >= 0? index : 0; i < list.Count; i++)
        {
            if (list[i].HistoryType == HistoryType.Cancelled)
            {
                return true;
            }
        }

        return list.Exists(delegate(HistoryEntry h) { return h.HistoryType == HistoryType.Cancelled; });
    }

I'm using C#2.0 syntax...

Oh and one more thing, make sure your HistoryEntry class implements IComparable:

public class HistoryEntry : IComparable<HistoryEntry>
{
    public DateTime Date { get; set; }
    public HistoryType HistoryType { get; set; }

    public int CompareTo(HistoryEntry other)
    {
        return this.Date.CompareTo(other.Date);
    }

}
BFree
Thanks, works great, but I think theres an error in the logic. If an index is found, and nothing occurs after it in the list that matches the comparison, it'll hit the return list.Exists() statement. I changed it to check for the existence of a Clear entry first, and if one doesn't exist return the list.Exists or continue to the for loop.
Brandon