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.

5
  • 2
    Possible duplicate of Read Csv using LINQ Commented Apr 7, 2019 at 20:19
  • Check out CSVHelper - you might try reading the CSV file manually and concatenating the column values into a string[] joshclose.github.io/CsvHelper/examples/reading/reading-by-hand Commented Apr 7, 2019 at 22:04
  • Why "using LINQ"? What difference does it make? Commented Apr 7, 2019 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. Commented Apr 8, 2019 at 0:04
  • Specifically, use File.ReadAllLines().Skip(1).ToArray(). Commented Apr 8, 2019 at 19:30

1 Answer 1

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!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.