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.
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.
I love the site blog.functionalfun.net for this exact purpose: the practical (and less practical, more fun) uses of LINQ. Ultimately, nearly everything he covers can be applied to real life situations, but he's started blogging blogging more "Practical LINQ" subjects for things he uses in business logic code that's interesting.
Bart De Smet's blog has some clever uses of LINQ such as Who ever said LINQ predicates need to be Boolean-valued?.
Robert Shelton of Microsoft was cool enough to list a few LINQ implementations for us:
As of month 7, 2008:
I'm rather surprised that Jon didn't mention his own....
Silly and clever at the same time ;-)
Edit:
oooh I forgot about this one as well. Ray tracing using Linq.
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.
Linq to Excel makes it a breeze to retrieve data from Excel spreadsheets. It takes care of creating the OLEDB connection and sql statement. All you have to do is tell it the file path to the spreadsheet and create the linq statement.
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;
}))