CSVHelper преобразует строку[][] в строку[]

#c# #string #csv #csvhelper

#c# #строка #csv #csvhelper

Вопрос:

У меня есть некоторые данные в формате csv, например

 string[][] items = new string[][] {
  new string[] { "dog", "3" },
  new string[] { "cat", "2" },
  new string[] { "bird", "1" }
};
  

теперь я хочу преобразовать входные данные в правильно отформатированные строки CSV и вернуть их — ожидаемый результат:

 string[] csvLines = {""dog";"3"", ""cat";"2"", ""bird";"1""};
  

или файл:

 "dog";"3"
"cat";"2"
"bird";"1"
  

что я пробовал:

 public static IEnumerable<string> GetCSVLines(string[][] list)
{
    using (MemoryStream stream = new MemoryStream())
    using (StreamWriter writer = new StreamWriter(stream))
    using (CsvHelper.CsvWriter csv = new CsvHelper.CsvWriter(writer))
    {
        foreach (var item in list)
        {
            foreach (var field in item)
            {
                csv.WriteField(field);
            }
            yield return csv.Record; //??
            csv.NextRecord();                  
        }                 
    }
}
  

Примечание: Я не могу просто использовать, string.Join() потому что поля могут содержать " разделитель ; или разрывы строк.

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

1. Какое это имеет отношение к CSVHelper? Простое Select и String.Format приведет к выводу

2. Вы хотите, чтобы выходные данные содержали экранированные двойные кавычки?

3. Ваш массив элементов понятен?

4. Почему бы просто не написать list.Select(pair=>String.Format(""{0}";"{1}"",pair[0],pair[1])).ToArray() ?

5. @Toshi вам придется объяснить, что вы пытаетесь сделать, иначе этот вопрос будет закрыт как неясный. Я подозреваю, что вы хотите преобразовать входные данные в правильно отформатированные строки CSV и вернуть их. Это не то, что задает вопрос, хотя «желаемый результат» имеет мало общего со строками CSV

Ответ №1:

Если вы хотите заключить элементы в кавычки (с помощью escapement: "ab"c" должно быть ""ab""c"" ) и Join их с помощью ; , вам не нужен CsvHelper простой Linq

   string[][] items = new string[][] {
    new string[] { "dog", "3" },
    new string[] { "cat", "2" },
    new string[] { "bird", "1" },
    new string[] { "e"sc", "4" } // escapment demo
  };

  string[] result = items
    .Select(line => string.Join(";", 
       line.Select(item => """   item.Replace(""", """")   """)))
    .ToArray();

  Console.Write(string.Join(Environment.NewLine, result));
  

Результат:

 "dog";"3"
"cat";"2"
"bird";"1"
"e""sc";"4"
  

Ответ №2:

Я бы сказал, что ответ @Dmitry Bychenko более прямолинеен, но если вы действительно хотели использовать CSVHelper, это возможно.

 public static IEnumerable<string> GetCSVLines(string[][] list)
{
    using (MemoryStream stream = new MemoryStream())
    using (StreamWriter writer = new StreamWriter(stream))
    using (CsvHelper.CsvWriter csv = new CsvHelper.CsvWriter(writer))
    using (StreamReader reader = new StreamReader(stream))
    {
        csv.Configuration.ShouldQuote = (field, context) => true;
        csv.Configuration.Delimiter = ";";

        foreach (var items in list)
        {
            foreach (var item in items)
            {
                csv.WriteField(item);
            }                    
            csv.NextRecord();

            writer.Flush();
            stream.Position = 0;

            yield return reader.ReadToEnd().TrimEnd('n');

            stream.Position = 0;
        }   
    }
}