Finding latest record in a List
-
21-06-2021 - |
Question
I have a list rms.PositiveResponse
, and another list rms.NegativeResponse
s. The Lists contain a RecruitID
and a Timestamp
. I have over 10,000 records.
I am getting this data from a web service.
The problem is finding if the latest update of a RecruitID
was a positive response or negative response. How can I determine that? I have the Timestamp
for each RecruitID
, the latest timestamp can tell me the latest update. How can I know what the latest update of a RecruitID
was so that I can store it in the database?
Here was my attempt, but this is very slow method of comparing , I want to know if there is a faster way.
RMSDataService.RMS rms = new RMSDataService.RMS();
var negList = rms.NegativeResponse.Where(d => d.RLMSTimeStamp != null && d.RLMSTimeStamp > new DateTime(2012, 02, 22));
var posList = rms.PositiveResponse.Where(d => d.RLMSTimeStamp != null && d.RLMSTimeStamp > new DateTime(2012, 02, 22));
foreach (var pos in posList)
{
foreach(var neg in negList)
{
if(neg.RLMSRecruitId == pos.RLMSRecruitId && neg.RLMSTimestamp > pos.RLMSTimestamp)
{
Console.WriteLine("Item fetched: RecruitId:{0} NegTimeStamp:{1} PosTimeStamp:{2}", neg.RLMSRecruitId, neg.RLMSTimeStamp, pos.RLMSTimeStamp);
}
}
}
Solution
Try this:
var negList = rms.NegativeResponse.Where(d => d.RLMSTimeStamp != null && d.RLMSTimeStamp > new DateTime(2012, 02, 22)).toList();
var posList = rms.PositiveResponse.Where(d => d.RLMSTimeStamp != null && d.RLMSTimeStamp > new DateTime(2012, 02, 22)).toList();
var item = (from pos in posList
join neg in negList
on
pos.RLMSRecruitId equals neg.RLMSRecruitId
orderby pos.RLMSTimestamp descending
select pos).FirstOrDefault();
OTHER TIPS
One way of looking at the question is that the main problem that you have is that you have no indicator on the source data as to whether the response is +ve or -ve. So, create a new list which does have that indicator and then you can easily find the record with the latest time for each Id and the response type.
e.g.
class Record {
public int Id { get; set; }
public DateTime Timestamp { get; set; }
}
private Record[] PositiveResponses = new[]{
new Record{ Id =1 , Timestamp = new DateTime(2012,1,1)},
new Record{ Id =1 , Timestamp = new DateTime(2012,1,2)},
new Record{ Id =2 , Timestamp = new DateTime(2012,1,3)},
new Record{ Id =2 , Timestamp = new DateTime(2012,1,5)}, // latest for id 2
new Record{ Id =3 , Timestamp = new DateTime(2012,1,8)},
new Record{ Id =4 , Timestamp = new DateTime(2012,1,8)} // latest for Id 4
};
private Record[] NegativeResponses = new[]{
new Record{ Id =1 , Timestamp = new DateTime(2012,1,1)},
new Record{ Id =1 , Timestamp = new DateTime(2012,1,3)}, // latest for Id 1
new Record{ Id =2 , Timestamp = new DateTime(2012,1,4)},
new Record{ Id =3 , Timestamp = new DateTime(2012,1,9)} // latest for id 3
};
[TestMethod]
public void GetLatest() {
var results = PositiveResponses.Select(r => new {
Id = r.Id,
Timestamp = r.Timestamp,
Type = "Pos"
})
.Union(
NegativeResponses.Select(r => new {Id = r.Id,
Timestamp = r.Timestamp,
Type = "Neg"}))
.GroupBy(r => r.Id)
.Select(grp => grp.OrderByDescending(r => r.Timestamp).First());
}
We select a new (anonymous) record from each list with the Id, Timestamp and a Type "Pos" or "Neg" and then union them into a new list.
Once we have the new list, it is easy to group by Id and then select the record with the highest timestamp. This record will have the Id, Timestamp and Pos/Neg indicator.