none
How to parse efficiently a Tab separated text file RRS feed

  • Question

  • Dear all,

    I have a text file which contains student home work mark, where datq gets separated by tabs delimiter as below sample

    Paul	Tom	Cris
    18       15      13
    21       45      23
    11       65      34
    76       45      23

    When parsing this file content, as a result I should be able to display column dedicated to Paul data or Tom or Cris data

    So the question is hoy can I parse those data properly in order that if I request data from paul, I should be able to get 18,21,11 and 76

    I have some trouble to figure out in which type of array or collection and in which form I could get all entries from correct person  store correctly ?

    Any idea or sample would help

    regards

    Monday, December 11, 2017 8:10 PM

Answers

  • Hello wakefun,

    If you want to get all students list, you should use list<list<string>> object to store value.

     private List<List<string>> ReadAllRecodes() {
    
                String[] content = File.ReadAllLines("T1.txt");
                
                var lls = new List<List<string>>();
                for (int i = 0; i < content.First().Split('\t').Length; i++) {
    
                    lls.Add(content.Select(x => x.Split('\t')[i]).ToList());
                }
                return lls;
            }
    

    If you also focus on efficiency, try to use Parallel.For.

    private List<List<string>> ReadAllRecodes() {
    
                String[] content = File.ReadAllLines("T1.txt");
                
                var lls = new List<List<string>>();
    
                Parallel.For(0, content.First().Split('\t').Length, i => lls.Add(content.Select(x => x.Split('\t')[i]).ToList()));
                return lls;
            }
    

    Best regards,

    Neil Hu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by wakefun Thursday, December 14, 2017 7:20 AM
    Wednesday, December 13, 2017 2:31 AM
    Moderator

All replies

  • Add a reference to Microsoft.VisualBasic then use code as shown below. I placed the output into a List<int> then used string.Join to display the values. If you need "Tom" use currentRow[1]

    public static void Demo()
    {
        var values = new List<int>();
        var fileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TextFile1.txt");
        using (Microsoft.VisualBasic.FileIO.TextFieldParser reader = new Microsoft.VisualBasic.FileIO.TextFieldParser(fileName))
        {
    
            reader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
            reader.Delimiters = new string[] { "\t" };
            string[] currentRow = null;
            int test = 0;
    
            while (!reader.EndOfData)
            {
                try
                {
                    currentRow = reader.ReadFields();
                    if (int.TryParse(currentRow[0],out test))
                    {
                        values.Add(test);
                    }
                }
                catch (Microsoft.VisualBasic.FileIO.MalformedLineException ex)
                {
                    Console.WriteLine("Line " + ex.Message + " is invalid.  Skipping");
                }
            }
        }
    
        Console.WriteLine(string.Join(",", values.ToArray()));
    }
    }


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites


    Monday, December 11, 2017 8:30 PM
    Moderator
  • You can do it with Linq with a projection into a custom object, which is being done in the example code.

    https://mlichtenberg.wordpress.com/2014/01/11/parsing-delimited-text-files-with-linq/

    What is a Linq projection?

    http://csharp-station.com/Tutorial/Linq/Lesson02

    Monday, December 11, 2017 10:58 PM
  • Hello wakefun,

    >>So the question is hoy can I parse those data properly in order that if I request data from paul

    You could get each line and split it to array by '\t'. Then obtain the elements that have the same index. Like

    Line1[0], Line2[0]... And the store result could be stored by either collection or array. The following is a simple example in using linq.

     private List<string> ReadPersonalScores(string Name) {
    
                String[] content=File.ReadAllLines("T1.txt");
    
                int index = Array.FindIndex(content.First().Split('\t'), x => x ==Name);
    
                return content.Select(x => x.Split('\t')[index]).ToList();
            }

    And the operate result is stored in list<string> object.

      List<string> result= ReadPersonalScores("Paul");

    Best regards,

    Neil Hu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by wakefun Tuesday, December 12, 2017 8:08 PM
    • Unmarked as answer by wakefun Tuesday, December 12, 2017 8:24 PM
    Tuesday, December 12, 2017 5:34 AM
    Moderator
  • Dear Da924x,

    Your approach is interresting but in your sample data is a line, in my case a complete dataset is a column

    As in my case the class will be based as the name of the student and a list of integer

    how can I do then ?

    regards



    Tuesday, December 12, 2017 8:24 PM
  • HOw can I get the full list in same way without specifyinh a name, but get all student list with theire respective marks ?

    regards

    Tuesday, December 12, 2017 8:25 PM
  • Hello wakefun,

    If you want to get all students list, you should use list<list<string>> object to store value.

     private List<List<string>> ReadAllRecodes() {
    
                String[] content = File.ReadAllLines("T1.txt");
                
                var lls = new List<List<string>>();
                for (int i = 0; i < content.First().Split('\t').Length; i++) {
    
                    lls.Add(content.Select(x => x.Split('\t')[i]).ToList());
                }
                return lls;
            }
    

    If you also focus on efficiency, try to use Parallel.For.

    private List<List<string>> ReadAllRecodes() {
    
                String[] content = File.ReadAllLines("T1.txt");
                
                var lls = new List<List<string>>();
    
                Parallel.For(0, content.First().Split('\t').Length, i => lls.Add(content.Select(x => x.Split('\t')[i]).ToList()));
                return lls;
            }
    

    Best regards,

    Neil Hu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by wakefun Thursday, December 14, 2017 7:20 AM
    Wednesday, December 13, 2017 2:31 AM
    Moderator