2

I have a comma separated values file (csv) and I want to open the csv file and read each line into an index of an array using LINQ in C#. I want to emphasize that I need this specifically in an array.

Subject,CourseCode,Class Nbr,Course Title,Days
LST,101,17297,The LST Experience,Th
RTO,101,13998,The RTO Experience,T

I want the first index of the array to be able to print the following

LST,101,17297,The LST Experience,Th //array[0]

And so on and so forth.

FranceMadrid
  • 95
  • 2
  • 10
  • 2
    Possible duplicate of [Read Csv using LINQ](https://stackoverflow.com/questions/5116604/read-csv-using-linq) – BartoszKP Apr 07 '19 at 20:19
  • Check out CSVHelper - you might try reading the CSV file manually and concatenating the column values into a `string[]` https://joshclose.github.io/CsvHelper/examples/reading/reading-by-hand/ – Levi Fuller Apr 07 '19 at 22:04
  • Why "using LINQ"? What difference does it make? – mason Apr 07 '19 at 22:12
  • 1
    Why not just use File.ReadAllLines() it makes no sense to use LINQ here unless you are trying to read each line into an object. – Kevin Apr 08 '19 at 00:04
  • Specifically, use `File.ReadAllLines().Skip(1).ToArray()`. – NetMage Apr 08 '19 at 19:30

1 Answers1

1

I want to open the csv file and read each line into an index of an array using LINQ in C#.

So let's split it into three separate parts:

  • Given a filename, open the file and read a sequence of lines
  • given a sequence of lines, change it into a sequence of [index, line]
  • given a sequence of [index, line] change it to the string format you want

And of course we want to do this all very LINQ-like, because we like LINQ (pun intended)

Let's do this writing extension functions. See Extension Methods Demystified

static class MyExtensionMethods
{
    // TODO add the extension methods
}

The first one: input a string fileName, output a sequence of lines (= strings)

public static IEnumerable<string> ReadLines(this string fileName)
{
    // TODO: check fileName not null, empty; check file exists
    FileInfo file = new FileInfo(fileName);
    using (TextReader reader = file.OpenText())
    {
        string line = reader.ReadLine();
        while (line != null)
        {
            yield return line;
            line = reader.ReadLine();
        }
    }

Convert a sequence of Lines into a sequence of [index, line]

IEnumerable<KeyValuePair<int, string>> ToIndexedLines(this IEnumerable<string> lines)
{
    return lines.Select( (line, index) => new KeyValuePair<int, string>(index, line));
}

And the third function: given a sequence of [index, line] convert it to a sequence of strings.

To make this re-usable I'll use a format string, so the caller can decide how to print his output. The format string has indexes {0} and {1}

IEnumerable<string> ToString(this IEnumerable<KeyValuePair<int, string>> indexLines,
   string formatString)
{
    // TODO: check input not null
    return indexLines.Select(keyValuePair =>
           String.Format(formatString, keyValuePair.Key, keyValuePair.Value);
}

After three one-liner functions we are able to read your file in a LINQ like fashion

const string fileName = "MyFile.Csv";
const string myFormatString = "{1} //array[{0}]";

IEnumerable<string> myRequestedOutput = fileName.ReadLines()
    .ToIndexedLines()
    .ToString(myFormatString);

Simple comme bonjour!

Harald Coppoolse
  • 28,834
  • 7
  • 67
  • 116