Как отделить строку и значение от словаря?

#c# #list #dictionary

#c# #Список #словарь

Вопрос:

У меня есть разделенная запятыми строка со следующими значениями:

 "File_name,cost_per_page,0.23,color_code,343,thickness,0.01".
  

Я хочу прочитать cost_per_page = 0,23, color_code = 343 и thickness = 0,01.

Как я могу это сделать? Я мог бы сделать это, поместив его в список и прочитав последовательный элемент рядом со строкой ключа. Есть ли какой-либо другой метод?

Комментарии:

1. С чем вы будете обращаться File_name ?

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

Ответ №1:

Самым простым (и, следовательно, вероятно, лучшим) подходом было бы просто использовать string.Split , а затем выполнить итерацию массива:

 var source = "File_name,cost_per_page,0.23,color_code,343,thickness,0.01";

var splitted = source.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries)
var result = new Dictionary<string, string>();
// Note: Starting from 1 to skip the "file_name"
// moving 2 indexes in each iteration, 
// and ending at length - 2.
for(int i = 1; i < splitted.Length - 1; i =2)
{
    result.Add(splitted[i], splitted[i 1]);
}
  

Я пытался найти умный способ сделать это с помощью linq, но лучшее, что я придумал, на самом деле совсем не такое умное:

 var valuesWithIndexes = source
    .Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries)
    .Skip(1)
    .Select((v, i) => new {v, i});

var keys = valuesWithIndexes.Where(x => x.i % 2 == 0);
var values = valuesWithIndexes.Where(x => x.i % 2 == 1);

var dictionary = keys.Zip(values, (k, v) => new {k, v})
    .ToDictionary(key => key.k,
                  val => val.v);
  

Я думаю, что простой цикл for является явным победителем в этом случае.

Ответ №2:

Я думаю, что это самый простой и наилучший подход.

 string str = "File_name,cost_per_page,0.23,color_code,343,thickness,0.01";

string[] array = str.Split(',');
Dictionary<string, double> dict = new Dictionary<string, double>();
for (int i = 1; i < array.Length - 1; i = i   2)
{
    string key = array[i];
    double value = Double.Parse(array[i   1], CultureInfo.InvariantCulture);
    dict.Add(key, value);
}
  

Вы также можете использовать приведенный выше код для строки большего размера (переменная str имеет больше пар ключ-значение).

Комментарии:

1. Чем это отличается от ответа, который я опубликовал за 7 минут до вас?

Ответ №3:

Я бы использовал linq. Преобразуйте строку в массив с разделителями.

Настройте словарь, содержащий первый элемент … не уверен, хотите ли вы это сделать. Если нет, просто удалите инструкции «d1» и «union».

Запустите какой-нибудь Linq, чтобы создать свой словарь на основе четных чисел.

Затем, если вы действительно хотите указать первый элемент, имя_файла, и вы хотите, чтобы он был в начале вашего словаря, тогда, наконец, вы должны выполнить инструкцию «union».

 string str = "File_name,cost_per_page,0.23,color_code,343,thickness,0.01";
string[] array = str.Split(',');

Dictionary<string, string> d1 = new Dictionary<string, string>()
{
    { array[0], "" }
};
Dictionary<string, string> d2 = array.Select((i, index) => (index > 0 amp;amp; index % 2 == 0) ?
    new { key = array[index - 1], value = i } : null).Where(i => i != null).ToDictionary(d => d.key, d => d.value);

Dictionary<string, string> result = d1.Union(d2).ToDictionary(k => k.Key, v => v.Value);

foreach (KeyValuePair<string, string> kvp in result)
    Console.WriteLine(kvp.Key   ": "   kvp.Value);

return;
  

другой и, вероятно, более чистый подход:

Это также учитывает File_name. Если вы этого не хотите, добавьте «index > 0» к условному оператору, где он проверяет четность.

 string str = "File_name,cost_per_page,0.23,color_code,343,thickness,0.01";
string[] array = str.Split(',');

Dictionary<string, string> d2 = array.Select((i, index) => (index % 2 == 0) ?
    new 
    {
        key = (index == 0) ? i : array[index - 1],
        value = (index == 0) ? "" : i
    } : null).Where(i => i != null).ToDictionary(d => d.key, d => d.value);

foreach (KeyValuePair<string, string> kvp in d2)
    Console.WriteLine(kvp.Key   ": "   kvp.Value);
  

Ответ №4:

Полный рабочий пример в этом скрипте.

Все, что вам нужно, это выполнить итерацию, пока вы не достигли конца вашего массива строк, гарантируя, что ваш индекс увеличится на 2 (имя поля, значение поля).

 int i = 1;
var temp = s.Split(',').ToList();
while(i < temp.Count) {
    i = i 2;
}