Разделить на KeyValuePair вместо массива

У меня есть строка данных:

Key1=Value1,Key2=Value2,KeyN=ValueN

Я пытаюсь разбить строку на

List<KeyValuePair<string, string>>

Я могу легко сделать это:

List<string[]> values = item.Split( ',' ).Select( p => p.Split( '=' ) ).ToList();

но я просто не могу понять, как добавить это в список KeyValuePair. Самое близкое, что я получил до сих пор, это:

List<KeyValuePair<string, string>> values = item.Split( ',' )
.Select( p => new KeyValuePair<string, string>(){ p.Split( '=' ) } ).ToList();

Но это еще немного :(

Я знаю, что могу легко сделать это с помощью цикла, но мне бы очень хотелось, чтобы он работал в Linq, поскольку практика делает его идеальным. Я уже видел немало примеров подобных вопросов, таких как этот, но я не могу соединить точки между этими вопросами и моим, поэтому, пожалуйста, простите меня, если я случайно разместил дубликат.

Любая помощь будет очень признательна, спасибо :)


person Storm    schedule 23.07.2013    source источник


Ответы (3)


То, что вы сделали до сих пор, хорошо. Тогда у вас есть два способа добиться желаемого:

Создайте метод ToKeyValuePair

public static KeyValuePair<string, string> ToKeyValuePair(string[] array)
{
    if (array.Length != 2)
        throw new ArgumentException("The array must contain exactly 2 elements.");

    return new KeyValuePair<string, string>(array[0], array[1]);
}

var values = (item.Split( ',' )
                  .Select( p => ToKeyValuePair(p.Split( '=' ))))
                  .ToList();

Используйте синтаксис запроса LINQ

Если я преобразую приведенную выше строку в синтаксис запроса:

var values = (from p in item.Split( ',' )
              select ToKeyValuePair(p.Split( '=' )))
             .ToList();

Не так много изменилось.

Но благодаря этому новому синтаксису довольно легко отказаться от использования ToKeyValuePair(...) благодаря предложению let:

var values = (from p in item.Split( ',' )
              let splittedP = p.Split( '=' )  // Declares a variable
              select new KeyValuePair<string, string>(splittedP[0], splittedP[1]))
             .ToList();

Конечно, последняя строка может быть написана с использованием синтаксиса расширенных методов (т. е. с .Select(p=>...)), но ее трудно читать:

var values = (item.Split(',')
                  .Select(p => new { p, splittedP = p.Split('=') })
                  .Select(p => new KeyValuePair<string, string>(p.splittedP[0], p.splittedP[1])))
                  .ToList();
person Cédric Bignon    schedule 23.07.2013
comment
Привет, Седрик! Большое спасибо за а). быстрый ответ и б). уровень детализации, на который вы пошли в объяснении, я действительно ценю это. Я пробую это в данный момент, и я вернусь к вам через секунду :) - person Storm; 23.07.2013
comment
Я попробовал второй вариант Linq, но получаю сообщение Невозможно неявно преобразовать тип System.Collections.Generic.KeyValuePair‹string,string›[] в System.Collections.Generic.List‹System.Collections.Generic.KeyValuePair ‹строка,строка›› - person Storm; 23.07.2013
comment
Последнее - волшебство, теперь я вижу, где я ошибся, такой момент Гомера, попытался соединить их вместе, а не разделить, спасибо, Седрик ;) - person Storm; 23.07.2013

Я знаю, что это старый вопрос, но я наткнулся на него в Google. Я решил проблему, используя принятый ответ, но немного сократил его. Вам не нужна часть new { p, splittedP = p.Split('=') }, только p.Split('=')

var values = data.Split(',').Select(p=>p.Split('='))
              .Select(s => new KeyValuePair<string, string>(s[0], s[1]))
              .ToList();

Вы также можете сделать что-то подобное, если ваши ключи уникальны:

var values = data.Split(',').Select(p => p.Split('='))
              .ToDictionary(k => k[0], v => v[1]);

Что намного короче и в основном дает вам список с доступом O (1).

(Это с .NET 4.5)

person Ryan Buddicom    schedule 30.03.2016

используйте приведенный выше код. надо подрезать ключ.

public static string GetUserInfo(this X509Certificate2 x509,X509Oid oid)
{
      try
      {
           var kvs = x509.Subject.Split(',').Select(x => new KeyValuePair<string, string>(x.Split('=')[0].Trim(), x.Split('=')[1].Trim())).ToList();

           string value = kvs.FirstOrDefault(A => A.Key == oid.ToString()).Value;
           return value;
       }
       catch (Exception)
       {   
       }
       return "";
}

Добавьте файл перечисления.

public enum X509Oid
{
        O,
        E,
        L,
        C,
        S,
        G,
        SN,
        CN,
        Street
}
person amazing    schedule 22.05.2019