What are some clever uses for LINQ outside of LINQ to SQL?
Have you found any problems that LINQ made a whole lot easier to solve? Please post examples.
Language-Integrated Query (LINQ) is the name for a set of technologies based on the integration of query capabilities directly into the C# language. Traditionally, queries against data are expressed as simple strings without type checking at compile time or IntelliSense support.
Advantages of Using LINQLINQ offers a common syntax for querying any type of data sources. Secondly, it binds the gap between relational and object-oriented approachs. LINQ expedites development time by catching errors at compile time and includes IntelliSense & Debugging support. LINQ expressions are Strongly Typed.
SQL isn't broken, so why fix it? Why do we need another querying language? The popular answer is that LINQ is INtegrated with C# (or VB), thereby eliminating the impedance mismatch between programming languages and databases, as well as providing a single querying interface for a multitude of data sources.
You can write LINQ queries in C# for SQL Server databases, XML documents, ADO.NET Datasets, and any collection of objects that supports IEnumerable or the generic IEnumerable<T> interface. LINQ support is also provided by third parties for many Web services and other database implementations.
Robert Shelton of Microsoft was cool enough to list a few LINQ implementations for us:
As of month 7, 2008:
I used LINQ to solve some of Project Euler in single C# statements. (Note that statements aren't the same as lines)
Beware: Evil nasty tricks.
//Euler 1
//Add all the natural numbers below one thousand that are multiples of 3 or 5.
Enumerable.Range(0, 1000).Where(i => i % 5 == 0 || i % 3 == 0).Sum()
//Euler 2
//Find the sum of all the even-valued terms in the sequence which do not exceed four million
//Enumerable.Repeat(new List<long>(1024){ 1, 1 }, 1).First(fib => Enumerable.Range(0, int.MaxValue).TakeWhile(i => fib.Last() <= 4000000)
.Aggregate(true, (u1, u2) => { fib.Add(fib.Last() + fib[fib.Count - 2]); return true; })).Where(n => n % 2 == 0).Sum()
//Euler 3 (>32bit)
//What is the largest prime factor of the number 600851475143?
Enumerable.Range(2, Int32.MaxValue - 2).Where(n => 600851475143 % n == 0 && Enumerable.Range(2, n / 2 - 1).All(f => n % f > 0)).Max()
//Euler 4
//Find the largest palindrome made from the product of two 3-digit numbers.
Enumerable.Range(100, 900).SelectMany(x => Enumerable.Range(100, 900).Select(y => x * y))
.Where(n => { var s = n.ToString(); return s.SequenceEqual(s.Reverse()); }).Max()
//Euler 5 (>32bit)
//What is the smallest number divisible by each of the numbers 1 to 20?
Enumerable.Range(20, Int32.MaxValue - 21).Where(n => Enumerable.Range(1, 20).All(i => n % i == 0)).First()
//Euler 6
//Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.
Math.Pow(Enumerable.Range(1, 100).Sum(), 2) - Enumerable.Range(1, 100).Select(i => i * i).Sum()
//Euler 7
//Find the 10001st prime.
Enumerable.Range(2, Int32.MaxValue - 1).Where(n => Enumerable.Range(2, n / 2 - 1).All(f => n % f > 0)).Skip(10000).First()
//Euler 8
//Discover the largest product of five consecutive digits in the 1000-digit number.
Enumerable.Range(0, 995).Select(i => "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450"
.Substring(i,5).Select(c => c - '0').Aggregate(1, (x, y) => x * y)).Max()
//Euler 10
//Find the sum of all the primes below two million.
Enumerable.Range(2, 2000000).Where(n => Enumerable.Range(2, n / 2 - 1).All(f => n % f > 0)).Select(x => (long)x).Sum()
Enumerable.Range(0, 168).Aggregate(Enumerable.Range(2, 2000000).Select(x => (long)x).ToList(), (result, index) => { result.RemoveAll(i => i > result[index] && i % result[index] == 0); return result; }).Sum()
Enumerable.Repeat(Enumerable.Range(2, 2000000).Select(x => (long)x).ToList(), 1).SelectMany(list => Enumerable.Range(0, Int32.MaxValue).Select(i => new { List = list, Index = i }))
.TakeWhile((g, i) => g.List[g.Index] * g.List[g.Index] <= 2000000 || i.Dump("Rounds") != i).Aggregate((List<long>) null, (result, g) => { g.List.RemoveAll(i => i > g.List[g.Index] && i % g.List[g.Index] == 0); return g.List; }).Sum()
Enumerable.Repeat(Enumerable.Range(2, 2000000).Select(x => (long)x).ToList(), 1).First(list => Enumerable.Range(0, Int32.MaxValue)
.TakeWhile(i => list[i] * list[i] <= 2000000 || i.Dump("Rounds")!=i).Aggregate(0, (count, i) => count + list.RemoveAll(j => j > list[i] && j % list[i] == 0)) != null).Sum()
//Euler 14
Enumerable.Range(1, 1000000).Select(s => Enumerable.Repeat(new List<long>(32) { s }, 1).First(list => Enumerable.Range(0, Int32.MaxValue).TakeWhile(i => list.Last() > 1)
.Aggregate(0, (index, unused) => { list.Add(list.Last() % 2 == 0 ? list.Last() / 2 : 3 * list.Last() + 1); return 1; }) == 1 || true))
.Aggregate(new List<long>(), (list, result) => list.Count <= result.Count ? result : list)
//Euler 19
//How many Sundays fell on the first of the month during the twentieth century?
Enumerable.Range(1901,100).SelectMany(y => Enumerable.Range(1,12).Select(m => new DateTime(y, m, 1))).Where(d => d.DayOfWeek == DayOfWeek.Sunday)
//Euler 21
//Evaluate the sum of all the amicable numbers under 10000.
Enumerable.Repeat(new Func<int, int>(n => Enumerable.Range(1, n / 2).Where(d => n % d == 0).Sum()), 1)
.Select(D => Enumerable.Range(1, 10000).Where(a => a == D(D(a)) && a != D(a)).Sum())
//Euler 34
//Find the sum of all numbers which are equal to the sum of the factorial of their digits.
Enumerable.Range(3, 40600).Where(n => n == n.ToString().Select(d => Enumerable.Range(1, d - '0').Aggregate(1, (r, i) => r * i)).Sum()).Sum()
//Euler 40
Enumerable.Repeat(new StringBuilder(), 1)
.Where(result => Enumerable.Range(0, Int32.MaxValue)
.TakeWhile(i => result.Length <= 1000000)
.Aggregate(result, (unused, index) => result.Append(index)) != null)
.Select(result => Enumerable.Range(1, 6).Select(i => result[(int)Math.Pow(10, i)] - '0')).First().Aggregate(1, (x, y) => x * y)
Other LINQ one-liners:
//Primes (Ineffecient)
Enumerable.Range(2, 1000000).Where(n => Enumerable.Range(2, n / 2 - 1).All(f => n % f > 0)).Count()
//Sieve of Eratosthenes
Enumerable.Range(0, 168)
.Aggregate(Enumerable.Range(2, 1000000).ToList(), (result, index) => {
result.RemoveAll(i => i > result[index] && i % result[index] == 0);
return result;
}).Count
//Prime Factors
Enumerable.Range(2,13195 / 2)
.Where(n => 13195 % n == 0
&& Enumerable.Range(2, n / 2 - 1).All(f => n % f > 0))
//Fibonacci
Enumerable.Repeat(new List<long>(32){ 1, 1 }, 1)
.First(fib => Enumerable.Range(0, 32).Aggregate(true, (u1, u2) => {
fib.Add(fib.Last() + fib[fib.Count - 2]);
return true;
}))
You should also check out Bindable LINQ, from the CodePlex site:
"Bindable LINQ is a set of extensions to LINQ that add data binding and change propagation capabilities to standard LINQ queries.
As well as propogating change, Bindable LINQ can analyse your queries at runtime and detect any dependencies your query has. If these dependencies provide events to subscribe to, Bindable LINQ will automatically monitor them for change. "
Here's one of the examples from the site:
Take this query for example:
contactsListBox.ItemsSource = from c in customers
where c.Name.StartsWith(textBox1.Text)
select c;
Bindable LINQ will detect that the query relies on the Text property of the TextBox object, textBox1. Since the TextBox is a WPF control, Bindable LINQ knows to subscribe to the TextChanged event on the control.
The end result is that as the user types, the items in the query are re-evaluated and the changes appear on screen. No additional code is needed to handle events.
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