Yesterday, Fred asked me if I could help him to convert C# code to LINQ. The solution may not obvious to find unless you know LINQ well. I will reproduce here the solution I gave Fred. Whether the LINQ version of the code is easier to read than the original one is arguable. The purpose here is more to show LINQ's Select query operator in action.
As you can see, the LINQ version is not so easy to understand and is verbose. Of course, we could use shorter names, but that wouldn't change the complexity of the query. The LINQ version is not as good in terms of performance either... So, should we use LINQ or not? My point here is that LINQ is not a "one size fits all" solution. You should use it wisely and avoid complexifying code by choosing always to use LINQ.
What's interesting in this example, is also simply the use of Select with a two-parameter lambda expression. You may know the version of Select that takes a single-parameter lambda well, but its counterpart is less known (and used).
This time we can’t use the query expression syntax because the variant of the Select operator that provides the index has no equivalent in this syntax. Notice that this version of the Select method provides an index variable that we can use in our lambda expression (precision not in the book: its not the name "index" that is important. You can use another name if you want. What makes the difference is that the lambda expression takes two parameters). The compiler automatically determines which version of the Select operator we want to use just by looking at the presence or absence of the index parameter. Notice also that we call Select before OrderBy. This is important to get the indices before the books are sorted, not after.
...One more tool in your toolbox. Now, use it wisely.
Somehow I missed that Where overload.
Adding a Select2 extension method for IEnumerable might help, here's how it shakes out in F#.