#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;
}