Can I cache partially-executed LINQ queries?
c#, linq
Solution
Sure, that's totally doable:
public static Func<A, double> ThrowIfNegative<A, double>(this Func<A, double> f)
{
return a=>
{
double r = f(a);
// if r is NaN then this will throw.
if ( !(r >= 0.0) )
throw new Exception();
return r;
};
}
public static Func<A, R> Memoize<A, R>(this Func<A, R> f)
{
var d = new Dictionary<A, R>();
return a=>
{
R r;
if (!d.TryGetValue(a, out r))
{
r = f(a);
d.Add(a, r);
}
return r;
};
}
And now...
Func<T, double> weight = whatever;
weight = weight.ThrowIfNegative().Memoize();
and you're done.
Problem
I have the following code: ``` IEnumerable<KeyValuePair<T, double>> items = sequence.Select(item => new KeyValuePair<T, double>(item, weight(item))); if (items.Any(pair => pair.Value<0)) throw new ArgumentException("Item weights cannot be less than zero."); double sum = items.Sum(pair => pair.Value); foreach (KeyValuePair<T, double> pair in items) {...} ``` Where `weight` is a `Func<T, double>`. The problem is I want `weight` to be executed as few times as possible. This means it should be executed at most once for each item. I could achieve this by saving it to an array. However, if any weight returns a negative value, I don't want to continue execution. Is there any way to accomplish this easily within the LINQ framework?