Link to home
Start Free TrialLog in
Avatar of dba123
dba123

asked on

Loop through my Generic list to find latest record based on Date

I have a list of records in my generic list.  Each record has this Date Field.  how can I determine from the entire list of records what record has the latest date easily?  Because I want to take that record and check another column's value once I find the latest record based on this date field in the list.

for example:

            // Create a generic list of claim records
            List<Claim> list = new List<Claim>();
            list = Claim.GetClaimListGeneric(WebUtils.ConnectionPrefix, ContractId);

            foreach (Claim claimrecord in list)
            {
                loop and find the latest record on lets say a field we call "UpdatedDate" here
                Once I find that record then I am going to check another columns value here or even
                after the foreach, not sure yet but I need to first find the latest record
            }
Avatar of JimBrandley
JimBrandley
Flag of United States of America image

Are you loading them from a DB or generating them yourself?

Jim
Avatar of dba123
dba123

ASKER

db.  Each item in the list is an object that represents a db record.  All I have to do is like this:

claim.MyDateField to check it
Avatar of dba123

ASKER

I mean claimrecord.fieldname so claimfield.Mydatefield....typical
You could just ORDER BY updatedate;
Then the last one returned is the most recent. Saves a lot of string compares in the list. DBs are very fast at that.

Jim
Avatar of dba123

ASKER

yea, but that's in SQL.  I don't want to create a proc just to do this.  Creating a ton of stored procs is not a good practice.  I'm going to do this by checking a generic list of objects (or records inother words) and check the fields there, to determine what the latest record is.
In fact, since you need to do more compares after that, could either order the set or reduce the size of the set (if you don't need them all for something else) by including the subsequent comparisons in the select as well.
Avatar of dba123

ASKER

>>>Saves a lot of string compares in the list. DBs are very fast at that.

yes, but you also do not want your list of stored procs to be thousands...your DB becomes unmanageable.  You should try to do this stuff in the business layer when possible and keep your # of procs at a maintainable level.  Generics are fast, so there is no performance lost in this case. Use the proc to get your list, then figure out and test against the values in C#
Avatar of dba123

ASKER

I need to loop through all the records in the generic list.  Then compare the previous date with the next.  But somehow I need to know that I'm at the endof the list and know which records is the latest.  I know this is easy in SQL but again, I'm not going to create a proc just for this one purpose.
Avatar of dba123

ASKER

I think you can sort a generic list and specify what field.
I wouldn't use a stored proc for that, just a simple select. But if you want to iterate the list,
int count = list.Count();
-- Do'nt know how your date is stored - string or Date adjust to fit.
if (count > 0)
{
   int latestIndex = 0;
   string latest = list[0].UpdateDate;
   int index = 0;
   while( index < count)
   {
      if (list[index].UpdateDate > latest)
      {
         latest = list[index].UpdateDate;
         latestIndex = index;
      }
      index++;
   }
Avatar of dba123

ASKER

hmm, good idea.  I'm seeing a for loop here instead let me try.
Avatar of dba123

ASKER

thanks for your help so far...still working on it and should have a solution by tomorrow morning.  I want to figure this out on the C# side and I think I'm almost there.
Good luck!

Jim
I would echo the benefits of doing it in a stored procedure. However, if you insist on doing it in code:

Claim latestClaim = null;
foreach (Claim claimrecord in list)
{
    if (latestClaim == null)
    {
        latestClaim = claimrecord;
        continue;
    }
    if (claimrecord.UpdateDate > latestClaim.UpdateDate)
    {
        latestClaim = claimrecord;
    }
}

If the latestClaim is null, the database contains no records. Otherwise latestClaim  will be the record with the most recent UpdateDate.

If you want to sort the list you can use:

list.Sort(
    delegate(Claim claimX, Claim claimY)
    {
        if (claimX == null)
        {
            if (claimY == null)
                return 0;
            return -1;
        }
        else
        {
            if (claimY == null)
                return 1;
            if (claimX.UpdateDate == claimY.UpdateDate)
                return 0;
            return (claimX.UpdateDate > claimY.UpdateDate) ? 1 : -1;
        }
    });
Avatar of dba123

ASKER

I sort of started my own but it's not quite there.  It's not really keep track of where I'm at in the list.  I need to check if it's the first record and if we're at teh end of the list on that first if statement

            int Odometer = 0;
            DateTime last;
            fistrecord = 0;

            // Create a generic list of claim records
            List<Claim> list = new List<Claim>();
            list = GetClaimListGeneric(WebUtils.ConnectionPrefix, ContractId);

            // Check for a latest Loss Odometer in generic list of claim records.  
            foreach (Claim claim in list)
            {
                last = claim.DateLossOccurred;
                fistrecord = 1;

                if ((firstrecord > 1) & (last > claim.DateLossOccurred))
                {
                    Odometer = claim.OdometerAtTimeOfLoss;
                }
                else
                {
                    last = claim.DateLossOccurred;
                }

                firstrecord++;
            }
Avatar of dba123

ASKER

I need to use that list.count and use a for loop in here somwehere to keep track if I'm at the end of the file or not.
That is tough with a foreach. You can detect the first, but not the last.

You can do that with a for loop or a while loop.
ASKER CERTIFIED SOLUTION
Avatar of JimBrandley
JimBrandley
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of dba123

ASKER

I may be making this harder than it really is.  Just trying to handle any null dates here but also set the initial variable

           int Odometer = 0;
            DateTime last = null;
         
            // Create a generic list of claim records
            List<Claim> list = new List<Claim>();
            list = GetClaimListGeneric(WebUtils.ConnectionPrefix, ContractId);

            // Check for a latest Loss Odometer in generic list of claim records.  
            foreach (Claim claim in list)
            {
                if ((last > claim.DateLossOccurred) & last != null)
                {
                    Odometer = claim.OdometerAtTimeOfLoss;
                }

                last = claim.DateLossOccurred;
            }


You need to change this:
                if ((last > claim.DateLossOccurred) & last != null)
                {
                    Odometer = claim.OdometerAtTimeOfLoss;
                }

to this:
                if ((last != nul)l && (last > claim.DateLossOccurred))
                {
                    Odometer = claim.OdometerAtTimeOfLoss;
                }

Avatar of dba123

ASKER

interesting way to  loop it, thanks Jim.  I think the only problem now is my comparison here between the dates but that's another issue

               if ((last != null) & (i > 1) & (last > claim.DateLossOccurred))
               {
                   Odometer = claim.OdometerAtTimeOfLoss;
               }

fails when you have a date of for example '12/29/1998 12:00:00 AM' for last and '12/29/1997 12:00:00 AM' for claim.DateLossOccurred.  I am not sure if > will work to compare dates.

anyway, thanks!
My pleasure. For the dates, you can load them into DateTime structs, and should be able to compare them.
Avatar of dba123

ASKER

thanks!