C# – Split string to dictionary as key,list

cc#-4.0

I have a string type which will return thousands of records in the format

key1,val1,val2,val3,val4,val5:key2,val6,val7,val8,val9,val10:key3,val11,val12,val13,val14,val15

I want to assign this to a dictionary as Key,List so it looks like

key1,[val1,val2,val3,val4,val5]

key2,[val6,val7,val8,val9,val10]

key3,[val11,val12,val13,val14,val15]

.
.
.

All keys are unique in the string and the List size is constant for all records.

At the moment I'm using Split and looping each record using

    //short example string - may contain 1000's
    string newstr = @"key1,val1,val2,val3,val4,val5:key2,val6,val7,val8,val9,val10:key3,val11,val12,val13,val14,val15";

    Dictionary<string, List<string>> mydictionary = new Dictionary<string, List<string>>();
    foreach (string item in newstr.Split(':'))
    {
        List<string> list = new List<string>(item.Split(','));
        mydictionary.Add(list[0], list);        
    }

My question is, is there a more efficient/quicker way of doing this for 1000's of records using C#4.0 rather than looping?

UPDATE: having tested the various answers the following are the 'correct' times

enter image description here

static void Main(string[] args)
{
    System.IO.StreamReader myFile =  new System.IO.StreamReader(@"C:\Users\ooo\Desktop\temp.txt");
    string newstr = myFile.ReadToEnd();
    myFile.Close();

    TimeSpan ts;
    TimeSpan te;
    Stopwatch stopWatch = new Stopwatch();
    stopWatch.Start();


    ts = stopWatch.Elapsed;
    Dictionary<string, List<string>> mydictionary = new Dictionary<string, List<string>>();
    foreach (string item in newstr.Split(':'))
    {
        List<string> list = new List<string>(item.Split(','));
        mydictionary.Add(list[0], list);
    }
    te = stopWatch.Elapsed;
    Console.WriteLine("MyTime: " + (te - ts).ToString());



    ts = stopWatch.Elapsed;
    var result = newstr.Split(':')
         .Select(line => line.Split(','))
         .ToDictionary(bits => bits[0],
                       bits => bits.Skip(1).ToList());
    te = stopWatch.Elapsed;
    Console.WriteLine("JonSkeet: " + (te - ts).ToString());


    ts = stopWatch.Elapsed;
    string[] keysAndValues = newstr.Split(':');
    var newdictionary = new Dictionary<string, List<string>>(keysAndValues.Length);
    foreach (string item in keysAndValues)
    {
        List<string> list = new List<string>(item.Split(','));
        newdictionary.Add(list[0], list);
    }
    te = stopWatch.Elapsed;
    Console.WriteLine("Joe: " + (te - ts).ToString());


    Console.WriteLine("Records: " + mydictionary.Count.ToString());


    stopWatch.Stop();
}

Best Answer

The following is potentially faster, as the Dictionary is constructed with the required capacity to avoid reallocations:

//short example string - may contain 1000's     
string newstr = ...;

string[] keysAndValues = newstr.Split(':');
var mydictionary = new Dictionary<string, List<string>>(keysAndValues.Length);
foreach (string item in keysAndValues)     
{         
    List<string> list = new List<string>(item.Split(','));         
    mydictionary.Add(list[0], list);
    // remove key from list to match Jon Skeet's implementation
    list.RemoveAt(0);
} 

Less readable than Jon Skeet's LINQ version though.