Order LINQ query elements by a collection of numbers

37 views Asked by At

This is a partially defined function that I'm using to retrieve the specified lines of a textfile, by passing the index of the lines I want:

Public Shared Function GetLines(ByVal sourceFilepath As String,
                                ByVal lineNumbers As IEnumerable(Of Integer)) As IEnumerable(Of String)

    Return File.ReadAllLines(sourceFilepath, encoding).
                Select(Function(line As String, index As Integer)
                            Return New With
                                   {
                                       Key .line = line,
                                       Key .index = index + 1
                                   }
                        End Function).
                Where(Function(con) lineNumbers.Contains(con.index)).
                OrderBy(Function(x) x.index.CompareTo(lineNumbers(x.index))).
                Select(Function(con) con.line)

End Function

Example usage:

GetLines("C:\file.txt", {1, 5, 6, 2} ' Linenumbers 1, 5, 6, and 2.

The problem is that I need to preserve the order of the lines, in the same order which I specified the indexes, so the function should order the query elements by that order {1, 5, 6, 2} but instead of that I get the lines in this order: {1, 2, 5, 6}.

How can I fix the evaluation that I'm doing at the OrderBy extension to return the expected results?.

1

There are 1 answers

2
Steven Doggart On BEST ANSWER

Change:

OrderBy(Function(x) x.index.CompareTo(lineNumbers(x.index)))

To:

OrderBy(Function(x) lineNumbers.ToList().IndexOf(x.index))

Alternatively, if you changed the type of the lineNumbers parameter from IEnumerable(Of Integer) to List(Of Integer), then you wouldn't need to call the ToList method.

Although, I have to say, while I love LINQ because it makes the code so much more readable, this is pushing the limits and is arguably less readable than writing the looping algorithm manually. But, to each their own :)