i found a sample code where lambda was used the code as follows
var sumOfgreaterThanSeven = numbers.Sum(n => n > 7 ? n : 0);
but the above code can be written as
var sumOfgreaterThanSeven = numbers.Sum(n > 7 ? n : 0);
so why user write lambda. please help me to understand why user write lambda here.
also tell me what is the advantage of lambda. thanks
The lambda is because you want to evaluate the conditional expression per item n. The version you added (Sum(n > 7 ? n : 0)) can't work - n isn't defined anywhere (the compiler message should be "The name 'n' does not exist in the current context").
The lambda can be read as:
given a term n, if n is greater than 7 return n, else return 0
and then sum over that logic.
Re the advantage - firstly, convenience - but also composition. For example, with LINQ-to-SQL I would absolutely expect that to issue something like:
select sum(case when row.col > 7 then row.col else 0 end)
from sometable row
of course, it might be better to use:
var sumOfgreaterThanSeven = numbers.Where(n => n > 7).Sum();
which would map to
select sum(row.col)
from sometable row
where row.col > 7
which might hit an index more accurately
You need to think of Lambda Expressions as methods.
n => n > 7 ? n : 0
Can in fact be written as
(n) => {
if(n > 7)
return n;
else
return 0;
}
Lambda expression will be converted to an anonymous method and an instance of Func<> will be created from it.
UPDATE
As Marc pointed out, this conversion to anonymous method and instance of Func<> or Action does not always happen -as rightly pointed out in Linq-to-sql. ... - but here it does, hence I pointed out the underlying.
When you write a lambda you are calling a method or evaluating an expression. The left side of the => is a set of parameters passed into the method/expression on the right side.
IEnumerableThing.Where(a => DoSomeStuff(a))
It's like writing this:
foreach (var a in IEnumerableThing)
{
DoSomeStuff(a);
}
In the case of the Sum() method you are really doing something like this:
int mysum = 0;
foreach (var n in whatever)
{
if (n > 7) { mysum += n; }
}
Related
I have the following code
int someCount = 0;
for ( int i =0 ; i < intarr.Length;i++ )
{
if ( intarr[i] % 2 == 0 )
{
someCount++;
continue;
}
// Some other logic for those not satisfying the condition
}
Is it possible to use any of the Array.Where or Array.SkiplWhile to achieve the same?
foreach(int i in intarr.where(<<condtion>> + increment for failures) )
{
// Some other logic for those not satisfying the condition
}
Use LINQ:
int someCount = intarr.Count(val => val % 2 == 0);
I definitely prefer #nneonneo's way for short statements (and it uses an explicit lambda), but if you want to build a more elaborate query, you can use the LINQ query syntax:
var count = ( from val in intarr
where val % 2 == 0
select val ).Count();
Obviously this is probably a poor choice when the query can be expressed with a single lambda expression, but I find it useful when composing larger queries.
More examples: http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b
Nothing (much) prevents you from rolling your own Where that counts the failures. "Nothing much" because neither lambdas nor methods with yield return statements are allowed to reference out/ref parameters, so the desired extension with the following signature won't work:
// dead-end/bad signature, do not attempt
IEnumerable<T> Where(
this IEnumerable<T> self,
Func<T,bool> predicate,
out int failures)
However, we can declare a local variable for the failure-count and return a Func<int> that can get the failure-count, and a local variable is completely valid to reference from lambdas. Thus, here's a possible (tested) implementation:
public static class EnumerableExtensions
{
public static IEnumerable<T> Where<T>(
this IEnumerable<T> self,
Func<T,bool> predicate,
out Func<int> getFailureCount)
{
if (self == null) throw new ArgumentNullException("self");
if (predicate == null) throw new ArgumentNullException("predicate");
int failures = 0;
getFailureCount = () => failures;
return self.Where(i =>
{
bool res = predicate(i);
if (!res)
{
++failures;
}
return res;
});
}
}
...and here's some test code that exercises it:
Func<int> getFailureCount;
int[] items = { 0, 1, 2, 3, 4 };
foreach(int i in items.Where(i => i % 2 == 0, out getFailureCount))
{
Console.WriteLine(i);
}
Console.WriteLine("Failures = " + getFailureCount());
The above test, when run outputs:
0
2
4
Failures = 2
There are a couple caveats I feel obligated to warn about. Since you could break out of the loop prematurely without having walked the entire IEnumerable<>, the failure-count would only reflect encountered-failures, not the total number of failures as in #nneonneo's solution (which I prefer.) Also, if the implementation of LINQ's Where extension were to change in a way that called the predicate more than once per item, then the failure count would be incorrect. One more point of interest is that, from within your loop body you should be able to make calls to the getFailureCount Func to get the current running failure count so-far.
I presented this solution to show that we are not locked-into the existing prepackaged solutions. The language and framework provides us with lots of opportunities to extend it to suit our needs.
Say I have a list of integers:
List<int> myInts = new List<int>() {1,2,3,5,8,13,21};
I would like to get the next available integer, ordered by increasing integer. Not the last or highest one, but in this case the next integer that is not in this list. In this case the number is 4.
Is there a LINQ statement that would give me this? As in:
var nextAvailable = myInts.SomeCoolLinqMethod();
Edit: Crap. I said the answer should be 2 but I meant 4. I apologize for that!
For example: Imagine that you are responsible for handing out process IDs. You want to get the list of current process IDs, and issue a next one, but the next one should not just be the highest value plus one. Rather, it should be the next one available from an ordered list of process IDs. You could get the next available starting with the highest, it does not really matter.
I see a lot of answers that write a custom extension method, but it is possible to solve this problem with the standard linq extension methods and the static Enumerable class:
List<int> myInts = new List<int>() {1,2,3,5,8,13,21};
// This will set firstAvailable to 4.
int firstAvailable = Enumerable.Range(1, Int32.MaxValue).Except(myInts).First();
The answer provided by #Kevin has a undesirable performance profile. The logic will access the source sequence numerous times: once for the .Count call, once for the .FirstOrDefault call, and once for each .Contains call. If the IEnumerable<int> instance is a deferred sequence, such as the result of a .Select call, this will cause at least 2 calculations of the sequence, along with once for each number. Even if you pass a list to the method, it will potentially go through the entire list for each checked number. Imagine running it on the sequence { 1, 1000000 } and you can see how it would not perform well.
LINQ strives to iterate source sequences no more than once. This is possible in general and can have a big impact on the performance of your code. Below is an extension method which will iterate the sequence exactly once. It does so by looking for the difference between each successive pair, then adds 1 to the first lower number which is more than 1 away from the next number:
public static int? FirstMissing(this IEnumerable<int> numbers)
{
int? priorNumber = null;
foreach(var number in numbers.OrderBy(n => n))
{
var difference = number - priorNumber;
if(difference != null && difference > 1)
{
return priorNumber + 1;
}
priorNumber = number;
}
return priorNumber == null ? (int?) null : priorNumber + 1;
}
Since this extension method can be called on any arbitrary sequence of integers, we make sure to order them before we iterate. We then calculate the difference between the current number and the prior number. If this is the first number in the list, priorNumber will be null and thus difference will be null. If this is not the first number in the list, we check to see if the difference from the prior number is exactly 1. If not, we know there is a gap and we can add 1 to the prior number.
You can adjust the return statement to handle sequences with 0 or 1 items as you see fit; I chose to return null for empty sequences and n + 1 for the sequence { n }.
This will be fairly efficient:
static int Next(this IEnumerable<int> source)
{
int? last = null;
foreach (var next in source.OrderBy(_ => _))
{
if (last.HasValue && last.Value + 1 != next)
{
return last.Value + 1;
}
last = next;
}
return last.HasValue ? last.Value + 1 : Int32.MaxValue;
}
public static class IntExtensions
{
public static int? SomeCoolLinqMethod(this IEnumerable<int> ints)
{
int counter = ints.Count() > 0 ? ints.First() : -1;
while (counter < int.MaxValue)
{
if (!ints.Contains(++counter)) return counter;
}
return null;
}
}
Usage:
var nextAvailable = myInts.SomeCoolLinqMethod();
Ok, here is the solution that I came up with that works for me.
var nextAvailableInteger = Enumerable.Range(myInts.Min(),myInts.Max()).FirstOrDefault( r=> !myInts.Contains(r));
If anyone has a more elegant solution I would be happy to accept that one. But for now, this is what I'm putting in my code and moving on.
Edit: this is what I implemented after Kevin's suggestion to add an extension method. And that was the real answer - that no single LINQ extension would do so it makes more sense to add my own. That is really what I was looking for.
public static int NextAvailableInteger(this IEnumerable<int> ints)
{
return NextAvailableInteger(ints, 1); // by default we use one
}
public static int NextAvailableInteger(this IEnumerable<int> ints, int defaultValue)
{
if (ints == null || ints.Count() == 0) return defaultValue;
var ordered = ints.OrderBy(v => v);
int counter = ints.Min();
int max = ints.Max();
while (counter < max)
{
if (!ordered.Contains(++counter)) return counter;
}
return (++counter);
}
Not sure if this qualifies as a cool Linq method, but using the left outer join idea from This SO Answer
var thelist = new List<int> {1,2,3,4,5,100,101};
var nextAvailable = (from curr in thelist
join next in thelist
on curr + 1 equals next into g
from newlist in g.DefaultIfEmpty()
where !g.Any ()
orderby curr
select curr + 1).First();
This puts the processing on the sql server side if you're using Linq to Sql, and allows you to not have to pull the ID lists from the server to memory.
var nextAvailable = myInts.Prepend(0).TakeWhile((x,i) => x == i).Last() + 1;
It is 7 years later, but there are better ways of doing this than the selected answer or the answer with the most votes.
The list is already in order, and based on the example 0 doesn't count. We can just prepend 0 and check if each item matches it's index. TakeWhile will stop evaluating once it hits a number that doesn't match, or at the end of the list.
The answer is the last item that matches, plus 1.
TakeWhile is more efficient than enumerating all the possible numbers then excluding the existing numbers using Except, because we TakeWhile will only go through the list until it finds the first available number, and the resulting Enumerable collection is at most n.
The answer using Except generates an entire enumerable of answers that are not needed just to grab the first one. Linq can do some optimization with First(), but it still much slower and more memory intensive than TakeWhile.
I'm working on some Project Euler questions and need some help understanding a solution I found.
My question is: Where the heck is X being set in the SkipWhile method call?? When I break the code during runtime and step through to that point I never see a value being set for it. Yet the code will work all the way through. I checked the definition for SkipWhile and maybe I just don't understand how the arguments being passed in the call satisfy the 3 parameter method definition. Same thing for Math.Pow - Where is that X getting set!?
public long FindGreatestPrimeFactor(long factorGreaterThan, long number)
{
long upperBound = (long)Math.Ceiling(Math.Sqrt(number));
// find next factor of number
long nextFactor = Range(factorGreaterThan + 1, upperBound)
.SkipWhile(x => number % x > 0).FirstOrDefault();
// if no other factor was found, then the number must be prime
if (nextFactor == 0)
{
return number;
}
else
{
// find the multiplicity of the factor
long multiplicity = Enumerable.Range(1, Int32.MaxValue)
.TakeWhile(x => number % (long)Math.Pow(nextFactor, x) == 0)
.Last();
long quotient = number / (long)Math.Pow(nextFactor, multiplicity);
if (quotient == 1)
{
return nextFactor;
}
else
{
return FindGreatestPrimeFactor(nextFactor, quotient);
}
}
}
private IEnumerable<long> Range(long first, long last)
{
for (long i = first; i <= last; i++)
{
yield return i;
}
}
I believe you are talking about the lambda expression:
x => number % x > 0
All lambda expressions use the lambda operator =>, which is read as "goes to". The left side of the lambda operator specifies the input parameters (if any) and the right side holds the expression or statement block.
In a LINQ expression, each item, when iterated over, is supplied to the lambda. In the body of the lambda, if you wish to refer to the item, you need to give it a name. In this case the parameter ends up named x.
The expressions that look like this:
x => number % x > 0
are called lambda expressions. They actually are functions, and x is a parameter. SkipWhile takes a function, and then executes it with different values for its parameters.
Here is how the lambda expression would be written as a function:
bool Foobar(long x)
{
return number % x > 0;
}
In SkipWhile, I believe the function is called with x being the first item in the list. If it is true, the function is called again with the second item in the list, and so on down until the function returns false.
In this case, SkipWhile is asking for a function that will convert a value of the type in the list to a bool. Lambda expressions are a concise way to express this.
SkipWhile is retrieving its input values (the x) from the Range method, which in turn returns numbers from factorGreaterThan + 1 up to upperBound. Not sure why the author decided to write a method for this, since this is built in with the Enumerable.Range method.
I am reading about anonymous methods and am trying to wrap my head around this example:
List<int> evenNumbers = list.FindAll(delegate(int i)
{ return (i % 2) == 0; } )
Why is delegate(int i) legal? You aren't having to declare new delegate void or anything like that.
Is that what is meant by anonymous method? Is this the added syntactic sugar that allows for anonymous methods?
It's legal because of what you suspect, it's creating an anonymous delegate/method.
An alternative (using the lambda operator =>) would be:
List<int> evenNumbers = list.FindAll((i) => ((i % 2) == 0));
or
List<int> evenNumbers = list.FindAll(i => i % 2 == 0);
See Lambda Expressions for further reading.
If you decompose the statement a little, hopefully it will be more obvious - this is the equivalent code.
Predicate<int> test = delegate(int i)
{
return (i % 2) == 0;
};
List<int> evenNumbers = list.FindAll(test);
As you can see it created an anonymous delegate (that the compiler will turn into a method behind the scenes)
Personally I've always found the "inline" anonymous delegate syntax to cloud the issue more than add clarity whereas the same construct built using a lambda expression, once you are used to the syntax, adds clarity
List<int> evenNumbers = list.FindAll(i => i % 2 == 0);
in this code it seems like passing a method into a method using a delegate.
Is it possible to implement McCarthy's amb-operator for non-deterministic choice in C#?
Apparently .NET lacks continuation support but yield return could be useful. Would this be possible in other static .NET-languages like F#?
Yes, yield return does a form of continuation. Although for many useful cases, Linq provides functional operators that allow you to plug together a lazy sequence generator, so in fact in C# 3 it isn't necessary to use yield return so much (except when adding more Linq-style extensions of your own to plug gaps in the library, e.g. Zip, Unfold).
In the example we factorise an integer by brute force. Essentially the same example in C# can be done with the built-in Linq operators:
var factors = Enumerable.Range(2, 100)
.Join(Enumerable.Range(2, 100),
n => 1, n => 1, (i, j) => new { i, j })
.First(v => v.i*v.j == 481);
Console.WriteLine("Factors are " + factors.i + ", " + factors.j);
Here the starting points are my two calls to Enumerable.Range, which is built-in to Linq but you could implement yourself as:
IEnumerable<int> Range(int start, int stop)
{
for (int n = start; n < stop; n++)
yield return n;
}
There are two odd parameters, the n => 1, n => 1 parameters to Join. I'm picking 1 as the key value for Join to use when matching up items, hence all combinations will match and so I get to test every combination of numbers from the ranges.
Then I turn the pair of values into a kind of tuple (an anonymous type) with:
(i, j) => new { i, j })
Finally, I pick the first such tuple for which my test is satisfied:
.First(v => v.i*v.j == 481);
Update
The code inside the call to First need not be merely a short test expression. It can be a whole lot of imperative code which needs to be "restarted" if the test fails:
.First(v =>
{
Console.WriteLine("Aren't lambdas powerful things?");
return v.i*v.j == 481;
);
So the part of the program that potentially needs to be restarted with different values goes in that lambda. Whenever that lambda wants to restart itself with different values, it just returns false - the equivalent of calling amb with no arguments.
This is not an answer to your question, but it may get you what you want.
amb is used for nondeterministic computing. As you may know, Prolog is a nondeterministic language using the notion of unification to bind values to variables (basically what amb ends up doing).
There IS an implementation of this functionality in C#, called YieldProlog. As you guessed, the yield operator is an important requisite for this.
http://yieldprolog.sourceforge.net/