2

I have a list of tuples

List<Tuple<string,string,string>>

The tuples represent <ID#, Session#, Date>

My mission is when the user wants to add a new ID#, I check to see (1) if that ID exists and if so, are we on the same Date. If so, I simply return that tuple (user makes use of the Session# and other stuff). If not, I create a new tuple, with the session id incremented by 1 and return that.

It seems to me to do this it would be desirable to group my tuples by ID, and then by Session#. I think this should be doable by LINQ (although using LINQ doesn't really matter). Note that efficiency is not really a concern. Readability is more important. I've seen many stackoverflow questions dealing with 2-Tuples, such as: Sort and Group in LINQ when I tried to adapt this to my problem, I lost my Date info.

How then to group by 3-tuples by ID, so I can find out if the ID I'm adding already exists and if so whether or not I need to create a new Session#.

Thanks, Dave

Based on Reed's answer, which I am marking as the answer, I am using the following code (which I'm sure a LINQ expert could improve!). I took Reed's central idea, and simply added a check to have the right session id. That is the id could exist, but we have a different date, and therefore a new session. The session id should be incremented by 1.

public static Tuple<string, string, string> GetPatientRecord(string ID)
    {
        DateTime dt = DateTime.Now;
        string newDate = dt.ToString("MMddyy-hhmmss");
        var match = tuples.FindAll(t => t.Item1 == ID);
        int maxSessionId = 0;
        if (match != null)
        {

            foreach (Tuple<string, string, string> tuple in match)
            {
                if (Int32.Parse(tuple.Item2) > maxSessionId)
                    maxSessionId = Int32.Parse(tuple.Item2);

                DateTime tupleDateTime = DateTime.ParseExact(tuple.Item3,"MMddyy-hhmmss",null);

                if (tupleDateTime.Date == dt.Date)
                    return tuple;
            }

        }
        // following lines will take care of case of no ID or ID present, but not this date
        Tuple<string, string, string> newTuple = new Tuple<string, string, string>(ID, (++maxSessionId).ToString(), newDate);
        tuples.Add(newTuple);
        return newTuple;
    }
Community
  • 1
  • 1
Dave
  • 8,095
  • 14
  • 56
  • 99
  • 2
    Are you sure you want to use a tuples here? If you are working with items much at all I would recommend making them first class POCO's instead of tuples to help indicate what their properties represent, reduce accidental errors and enhance maintainability of your code. – Kevin Feb 10 '14 at 20:24
  • @Kevin I do agree 100% with that - but it actually doesn't really change the code much (other than using `.ID` instead of `.Item1`, etc... – Reed Copsey Feb 10 '14 at 20:35
  • @ReedCopsey Agreed... I upvoted your answer. I just wanted to make a style comment in case I ever inherited code from Dave or someone else reading this. :) – Kevin Feb 10 '14 at 20:38
  • Kevin, Yes POCOs would be fine but as Reed points out, the question is still the same: If the user adds a new ID, how do I see if there is a POCO (or tuple) already existing that is a good match. It a LINQ question as much as anything. Again, I can find examples for 2-Tuples but my limited experience with LINQ (or limited intelligence!) has stopped me from extending the examples to 3 -tuples (let alone POCOs). Thanks for reading. – Dave Feb 10 '14 at 20:53
  • @Dave It'd be better to store integers and DateTime directly, btw, instead of using strings for everything. And switching to a POCO would be a good idea, too ;) – Reed Copsey Feb 10 '14 at 23:27

1 Answers1

3

You can use GroupBy with the two tuple items by making an anonymous type (ie: ...GroupBy(t => new { t.Item1, t.Item3 }), but in this case, since you're just trying to find a single match, I'd use FirstOrDefault:

var match = tuples.FirstOrDefault(t => t.Item1 == ID && t.Item3 == theDate);

if (match != null)
   return match;

// Build new tuple as needed
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Thanks Reed. Marked as answer. I needed to add slightly more code which I put in my edited question. I'm using your central ideas however. – Dave Feb 10 '14 at 23:02