I often find myself wanting to use Head and Tail methods on IEnumerables, which don't exist as part of Linq. While I could easily write my own I wonder whether they have been purposefully left out. For example,
var finalCondition = new Sql("WHERE @0 = @1", conditions.Head().Key, conditions.Head().Value);
foreach (var condition in conditions.Tail())
{
finalCondition.Append("AND @0 = @1", condition.Key, condition.Value);
}
So, what is the best practice regarding this with Linq? Is the fact that I keep finding uses for this a sign that I am not doing something recommended? If not then why was this common functional paradigm not implemented in Linq?
Technically, your Head would be .First() and your Tail would be .Skip(1). But maybe you can find a better solution? Like using .Aggregate() on your IEnumerable?
Given the interface of IEnumerable<T>
, performance can not always be ensured.
You note that most functional programming languages implement tail and head. However it should be noted that these languages are acting on in memory constructs.
IEnumerable<T>
does not have any such constraints, and thus it cannot be assumed that this would be efficient.
A common functional pattern for example would be to recursively work on the Head of a collection and then recurse on the Tail of the call...
If you did this with Entity Framework for instance, you would send the following (meta) call to the SQL server, tight looped.
Select * from
(
Select * from
(
Select * from
(...)
Skip 1
)
Skip 1
);
Which would be highly inefficient.
EDIT:
Come to think about it. Another reason, is that C#/VB.Net doesn't support tail recursion, and thus, this pattern can easily cause a StackOverflow
.
Because the "Head & Tail" concept is used in functional programming for pattern matching and recursive calls. Since C # does not support pattern matching, then there is no need to implement head() and tail () methods.
let rec sum = function
| [] -> 0
| h::t -> h + sum t
As for your case - you should use Aggregate method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With