-1

I am trying to read lines from a file but I want to exclude lines with irrelevant characters. I only want lines that contain alphabetic characters to be printed. Also once a line has been printed I do not want it to be printed again. Here is my current code:

`string[] lines = System.IO.File.ReadAllLines(@"File Location");  //Create line array..
Random rnd1 = new Random(); //Random value

Console.ReadKey();

Console.WriteLine("Contents of file.txt:");
foreach (string line in lines)
{
Console.WriteLine(lines[rnd1.Next(lines.Length)]); //Print random line
}

`

AB147
  • 9
  • 3
  • So a line that has a space, a number, an apostrophe or any punctuation in it will be skipped, correct? Some sample input and output would be helpful. – Rufus L Nov 29 '18 at 03:07
  • Yes. For example a line like "I took a walk" would be chosen and printed randomly. A line like "I took a walk (at the beach)" would be skipped as it contains brackets. – AB147 Nov 29 '18 at 03:09
  • But the first one contains spaces...any other non-alphabetic characters allowed? – Rufus L Nov 29 '18 at 03:10
  • Your question is unclear. You've said *only alphabetic characters*, but your example (not in the question where it belongs, but buried in a comment) shows space characters.What about punctuation (commas, periods, question marks)? What about Unicode characters (that are not A-Z or a-z)? Are they allowed? Please [edit] your post to make it more clear what you're asking, and include your efforts to do something to solve the problem before posting here. Do not add information that is relevant to the question in comments; instead, [edit] the question and add it there where it can be easily seen. – Ken White Nov 29 '18 at 03:17
  • A quick search here found [this post](https://stackoverflow.com/q/3519539/62576), which has some answers that should help you at least make an effort to do something yourself. – Ken White Nov 29 '18 at 03:24
  • `var lines = File.ReadLines(@"File Location").Where(LineFilterFunc).ToList()` maybe? – vasily.sib Nov 29 '18 at 03:25

1 Answers1

0

One way to do it would be to filter the lines as you read them in from the file. We can do this by treating each line as a character array, excluding acceptable non-alpha-numeric characters by passing them as an IEnumerable to the Linq extension method .Except(), and then we can test that .All of the remaining characters are alphabetic by calling the IsLetter method of the char struct (which returns true if the character is a letter).

For example:

Random random = new Random();

static void Main()
{
    // Valid non-alphanumeric characters are stored in this list.
    // Currently this is only a space, but you can add other valid
    // punctuation here (periods, commas, etc.) if necessary.
    var validNonAlphaChars = new List<char> {' '};

    // Get all lines that contain only letters (after
    // excluding the valid non-alpha characters).
    var fileLines = File.ReadAllLines(@"c:\temp\temp.txt")
        .Where(line => line.Except(validNonAlphaChars).All(char.IsLetter))
        .ToList();

    // Shuffle the lines so they're in a random order using the Fisher-Yates
    // algorithm (https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle)
    for (int i = 0; i < fileLines.Count; i++)
    {
        // Select a random index after i
        var rndIndex = i + random.Next(fileLines.Count - i);

        // Swap the item at that index with the item at i
        var temp = fileLines[rndIndex];
        fileLines[rndIndex] = fileLines[i];
        fileLines[i] = temp;
    }

    // Now we can output the lines sequentially from fileLines
    // and the order will be random (and non-repeating)
    fileLines.ForEach(Console.WriteLine);

    GetKeyFromUser("\nPress any key to exit...");
}
Rufus L
  • 36,127
  • 5
  • 30
  • 43
  • 1
    another approch is to shuffle and output in one turn: `while(fileLines.Count > 0) { var i = random.Next(fileLines.Count); Console.WriteLine(fileLines[i]); fileLines.RemoveAt(i); }` – vasily.sib Nov 29 '18 at 03:45