Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq to convert a string to a Dictionary<string,string>

I'm using a dictionary to hold some parameters and I've just found out that it's not possible to serialize anything that implements IDictionary (unable to serialize IDictionary).

As a workaround I'd like to convert may dictionary into a string for serialization and then convert back to a dictionary when required.

As I'm trying to improve my LINQ this seems like a good place to do it but I'm not sure how to start.

This is how I'd implement it without LINQ:

/// <summary>
/// Get / Set the extended properties of the FTPS processor
/// </summary>
/// <remarks>Can't serialize the Dictionary object so convert to a string (http://msdn.microsoft.com/en-us/library/ms950721.aspx)</remarks>
public Dictionary<string, string> FtpsExtendedProperties
{
    get 
    {
        Dictionary<string, string> dict = new Dictionary<string, string>();

        // Get the Key value pairs from the string
        string[] kvpArray = m_FtpsExtendedProperties.Split('|');

        foreach (string kvp in kvpArray)
        {
            // Seperate the key and value to build the dictionary
            string[] pair = kvp.Split(',');
            dict.Add(pair[0], pair[1]);
        }

        return dict; 
    }

    set 
    {
        string newProperties = string.Empty;

        // Iterate through the dictionary converting the value pairs into a string
        foreach (KeyValuePair<string,string> kvp in value)
        {
            newProperties += string.Format("{0},{1}|", kvp.Key, kvp.Value);    
        }

        // Remove the last pipe serperator
        newProperties = newProperties.Substring(0, newProperties.Length - 1);
    }
}
like image 338
TeamWild Avatar asked Sep 05 '11 10:09

TeamWild


2 Answers

try something like this

var dict = str.Split(';')
              .Select(s => s.Split(':'))
              .ToDictionary(a => a[0].Trim(), a => a[1].Trim()));

above one is true for the following kind of string

"mykey1:myvalue1; mykey2:value2;...."
like image 166
Pranay Rana Avatar answered Oct 12 '22 22:10

Pranay Rana


In the context of your code

/// Get / Set the extended properties of the FTPS processor
/// </summary>
/// <remarks>Can't serialize the Dictionary object so convert to a string (http://msdn.microsoft.com/en-us/library/ms950721.aspx)</remarks>
public Dictionary<string, string> FtpsExtendedProperties
{
get 
{

Dictionary<string, string> dict = m_FtpsExtendedProperties.Split('|')
      .Select(s => s.Split(','))
      .ToDictionary(key => key[0].Trim(), value => value[1].Trim());

    return dict; 
}

set 
{

        // NOTE: for large dictionaries, this can use
        // a StringBuilder instead of a string for cumulativeText

        // does not preserve Dictionary order (if that is important - reorder the String.Format)
    string newProperties = 
              value.Aggregate ("",
                      (cumulativeText,kvp) => String.Format("{0},{1}|{2}", kvp.Key, kvp.Value, cumulativeText));

        // Remove the last pipe serperator
        newProperties = newProperties.Substring(0, newProperties.Length - 1);

        }
    }

Haven't tested this, but the functions used should give you some idea of how to do it fairly succinctly with LINQ

like image 31
Neil Fenwick Avatar answered Oct 13 '22 00:10

Neil Fenwick