How to: Sort or Filter Text Data by Any Word or Field (LINQ)

The following example shows how to sort lines of structured text, such as comma-separated values, by any field in the line. The field may be dynamically specified at runtime. Assume that the fields in scores.csv represent a student's ID number, followed by a series of four test scores.

To create a file that contains data

Example

Class SortLines

    Shared Sub Main()
        Dim scores As String() = System.IO.File.ReadAllLines("../../../scores.csv")

        ' Change this to any value from 0 to 4 
        Dim sortField As Integer = 1

        Console.WriteLine("Sorted highest to lowest by field " & sortField)

        ' Demonstrates how to return query from a method. 
        ' The query is executed here. 
        For Each str As String In SortQuery(scores, sortField)
            Console.WriteLine(str)
        Next 

        ' Keep console window open in debug mode.
        Console.WriteLine("Press any key to exit.")
        Console.ReadKey()

    End Sub 

    Shared Function SortQuery(ByVal source As IEnumerable(Of String), ByVal num As Integer) _
                            As IEnumerable(Of String)
        Dim scoreQuery = From line In source _
                         Let fields = line.Split(New Char() {","c}) _
                         Order By fields(num) Descending _
                         Select line

        Return scoreQuery
    End Function 
End Class 
' Output: 
' Sorted highest to lowest by field 1 
' 116, 99, 86, 90, 94 
' 120, 99, 82, 81, 79 
' 111, 97, 92, 81, 60 
' 114, 97, 89, 85, 82 
' 121, 96, 85, 91, 60 
' 122, 94, 92, 91, 91 
' 117, 93, 92, 80, 87 
' 118, 92, 90, 83, 78 
' 113, 88, 94, 65, 91 
' 112, 75, 84, 91, 39 
' 119, 68, 79, 88, 92 
' 115, 35, 72, 91, 70
public class SortLines
{
    static void Main()
    {
        // Create an IEnumerable data source 
        string[] scores = System.IO.File.ReadAllLines(@"../../../scores.csv");

        // Change this to any value from 0 to 4. 
        int sortField = 1;

        Console.WriteLine("Sorted highest to lowest by field [{0}]:", sortField);

        // Demonstrates how to return query from a method. 
        // The query is executed here. 
        foreach (string str in RunQuery(scores, sortField))
        {
            Console.WriteLine(str);
        }

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }

    // Returns the query variable, not query results! 
    static IEnumerable<string> RunQuery(IEnumerable<string> source, int num)
    {
        // Split the string and sort on field[num] 
        var scoreQuery = from line in source
                         let fields = line.Split(',')
                         orderby fields[num] descending 
                         select line;

        return scoreQuery;
    }
}
/* Output (if sortField == 1):
   Sorted highest to lowest by field [1]:
    116, 99, 86, 90, 94
    120, 99, 82, 81, 79
    111, 97, 92, 81, 60
    114, 97, 89, 85, 82
    121, 96, 85, 91, 60
    122, 94, 92, 91, 91
    117, 93, 92, 80, 87
    118, 92, 90, 83, 78
    113, 88, 94, 65, 91
    112, 75, 84, 91, 39
    119, 68, 79, 88, 92
    115, 35, 72, 91, 70
 */

This example also demonstrates how to return a query variable from a Function (Visual Basic) or method (C#).

Compiling the Code

  • Create a Visual Studio project that targets the .NET Framework version 3.5. By default, the project has a reference to System.Core.dll and a using directive (C#) or Imports statement (Visual Basic) for the System.Linq namespace. In C# projects, add a using directive for the System.IO namespace.

  • Copy this code into your project.

  • Press F5 to compile and run the program.

  • Press any key to exit the console window.

See Also

Concepts

LINQ and Strings