Use LINQ with an embedded lambda expression to find prime numbers in C# (Part 3 of 3)

[prime numbers]

The example Use more efficient LINQ to find prime numbers in C# (Part 2 of 3) uses a LINQ query to find prime numbers. It creates a delegate variable named IsOddPrime referring to a lambda expression and uses it to determine whether a number is prime and should therefore be selected.

It occurred to me that you should be able to use a lambda expression directly in the LINQ query without assigning it to a delegate variable. Unfortunately, I couldn’t find any examples. All of the examples I found created a query without a where clause and then called the query’s Where method passing it a lambda expression. After some trial and error, I found that the following query works.

var primes =
    from number in Enumerable.Range(1, max / 2)
    where (
        (Func<int, bool>)(n =>
            {
                for (int i = 3; i * i <= n; i += 2)
                    if (n % i == 0) return false;
                return true;
            }
        )
    )(2 * number + 1)
    select 2 * number + 1;

The lambda expression is shown in blue.

The code casts the lambda expression into a Func<int, bool>, a function that takes an int as a parameter and returns a bool result. The cast operator is shown in green.

The code wraps the result in parentheses to ensure that the cast operator is applied. It then invokes the method passing it the value 2 * number + 1.

I think the previous version is easier to understand and the two should have the same performance. This version is basically an exercise in figuring out how to use an embedded lambda expression in a LINQ query. See the previous example for more details on how the rest of the program works.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in algorithms, LINQ, mathematics and tagged , , , , , , , , , , . Bookmark the permalink.

4 Responses to Use LINQ with an embedded lambda expression to find prime numbers in C# (Part 3 of 3)

  1. Ello says:
    public static IEnumerable PrimeNumbers()
    {
        yield return 2;
        for (int i = 3; i  insertNumberHere <= 1000000)
            .ForEach(Console.WriteLine);
  2. Ello says:
    public static IEnumerable PrimeNumbers()
    {
        yield return 2;
        for (int i = 3; i <= int.MaxValue; i += 2)
        {
            if (IsOddPrime(i))
            {
                yield return i;
            }
        }
    }
    
    private static bool IsOddPrime(int number)
    {
        for (int i = 3; i * i <= number; i += 2)
            if (number % i == 0) return false;
        return true;
    }
  3. Ello says:
    PrimeNumbers()
        .TakeWhile(insertNumberHere => insertNumberHere <= 1000000)
        .ForEach(Console.WriteLine);
    • RodStephens says:

      Yes, you can do some interesting things with yield return. For example, you could use a number sieve to get better performance. Although if you want performance, you may not want to use LINQ.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.