Background: I am trying to write a shortest possible lambda expression to find the greatest of 3 numbers. Of course ternery operator is capable of doing it.
Func<int, int, int, int> greatestNumber2 = (x, y, z) => (x > y) ? ((x > z) ? x : z) : ((y > z) ? y : z);
But my intention is to achieve a function such as the one below.
greatest (x, y, z) = if (greater (x, y)>z) then greater(x, y) else z;
I was able to do this in two ways.
Func<int, int, int> greaterNumber = null;
Func<int, int, int, int> greatestNumber = null;
//Expression 1
greaterNumber = (x, y) => x > y ? x : y;
greatestNumber = (x, y, z) => greaterNumber(x, y) > z ? greaterNumber(x, y) : z;
//Expression 2
greatestNumber = (x, y, z) => {
Func<int, int, int> greater = (i, j) => i > j ? i : j;
return greater(x, y) > z ? greater(x, y) : z;
};
In the Expression 2, I was able to somehow achieve the what I wanted i.e define the function to find the greater among two numbers from the same expression itself. However, it is a statment lambda.
Is there a way to write a single lined lambda to define and use the greater of 2 numbers from within the expressi开发者_运维技巧on of greatest itself.
How about something along the lines of:
Func<int, int, int, int> greatest = (x, y, z) => Math.Max(x, Math.Max(y, z));
Sample test application:
using System;
class Program
{
static void Main(string[] args)
{
Func<int, int, int, int> greatest = (x, y, z) => Math.Max(x, Math.Max(y, z));
Console.WriteLine(greatest(1, 2, 3));
Console.WriteLine(greatest(1, 3, 2));
Console.WriteLine(greatest(2, 1, 3));
Console.WriteLine(greatest(2, 3, 1));
Console.WriteLine(greatest(3, 1, 2));
Console.WriteLine(greatest(3, 2, 1));
}
}
How about building an array and using LINQ? Probably a bit easier to extend than working out all the logic paths with multiple inputs (untested):
Func<int, int, int, int> f = (x, y, z) => new[] { x, y, z }.Max();
EDIT: Just reread the question, it looks like you want to recurse the greatestNumber
lambda, with just one lambda definition. I don't think you could do that, as greatestNumber(x,y)
's signature is different to greatestNumber(x,y,z)
. You could probably do something more generalised with a normal function that takes a params
argument, but that doesn't involve lambdas.
EDIT 2: As @Anthony says, creating an array is probably overkill, although it is short and a one-liner. You could simplify your Expression 2 a bit:
Func<int, int, int> greaterOf = (x, y) => x > y ? x : y;
Func<int, int, int, int> greaterOf = (x, y, z) => greaterOf(x, greaterOf(y, z));
精彩评论