OllieVanD
OllieVanD

Reputation: 47

Store text into a list separated by delimiters using objects and methods

I'm currently trying to read a large piece of text saved under the string TestFile, shown below. I then want to go through each line and add each word split by the delimiters to the list. I've managed to do this successfully for an array (with very different code of course), however I've not used lists before and I'm also trying to incorporate classes and methods into my coding. I'm aware the below wont work as the object isn't returning any value from the method(?), however I don't know how that's meant to be done. Any help or some good resources on lists or objects would be very much appreciated.

using System;
using System.IO;
namespace Summarizer
{
    class Reader
    {
        public static void Main(string[] args)
        {
            string TestFile = @"C:\Users\ollie\Desktop\Test\Target\PracticeHolmes.txt";
            ReadList TestRead = new ReadList(TestFile);
    }
}
  class ReadList
    {
        private string line;
        private char[] delimiters = { ' ', '.', ',', '!', '?' };

        public ReadList(string TestFile)
        {
            StreamReader tr = new StreamReader(TestFile);
            
            while ((line = tr.ReadLine()) != null)
            {
                line.Split(delimiters);
                TestRead.Add(line);
            }
        }
}
   

Upvotes: 1

Views: 309

Answers (2)

dbc
dbc

Reputation: 116991

You can read your TestFile into a list of words with one line of code via a LINQ expression:

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

class ListReader
{
    private char[] delimiters = { ' ', '.', ',', '!', '?' };

    public List<string> Read(string fileName) =>
        File.ReadLines(fileName).SelectMany(l => l.Split(delimiters)).ToList();
}

And to use the ListReader class, do:

var list = new ListReader().Read(TestFile);

Notes:

  • An array T [] represents a list of fixed size. Once allocated you can replace items in the array but you cannot expand or shrink the array.

  • A List<T> represents a resizable list. You would use a list to represent a sequential collection of objects that can be accessed by index and to which you might later want to add or remove items.

  • File.ReadLines() enumerates through all the lines in a text file without loading the entire file into memory. It thus does the same thing as your while ((line = tr.ReadLine()) != null) loop in fewer lines of code.

  • SelectMany() and ToList() are extension methods from the System.Linq namespace, and allow projecting an enumeration into a enumeration of enumerations then flattening the result (here, projecting each line into an array of words, then flattening that into a sequence of words) and then materializing the enumeration into a list.

  • If you only needed the distinct words (i.e. the list of words with duplicates removed) you could use the .Distinct() extension method like so:

     public List<string> ReadDistinct(string fileName) =>
         File.ReadLines(fileName).SelectMany(l => l.Split(delimiters)).Distinct().ToList();
    

Upvotes: 1

Mr Balanikas
Mr Balanikas

Reputation: 1681

There is a more convenient way to read lines from a text file, File.ReadAllLines(TestFile) Also, don't forget to store the words somewhere, i.e. store the returned value from line.Split(delimiters)

Here is a complete example:

            string TestFile = @"C:\Users\ollie\Desktop\Test\Target\PracticeHolmes.txt";
            var lines = File.ReadAllLines(TestFile);
            var words = new List<string>();
            char[] delimiters = { ' ', '.', ',', '!', '?' };
            foreach (var line in lines)
            {
                words.AddRange(line.Split(delimiters));
            }

As for the "using objects and methods" part of the question, you can construct a class that handles what you aim to do. Lets call it Reader. Now, what do you want the reader to do for you? The reader should be able to take some input (the file or file path) and produce some output (the parsed words). You can add a method that does precisely that, lets call it Read. With that, your code could look something like this:

    class Reader
    {
        string[] Read(string filePath)
        {
            // construct and return the words;
        }
    }

Upvotes: 1

Related Questions