.
public void Listing_5_13_ToLookupOperator()
{
var contacts = Contact.SampleData();
var calls = CallLog.SampleData();
// build a lookup list for the inner sequence
var calls_lookup =
(from c in calls
orderby c.When descending
select c)
.ToLookup(c => c.Number);
// one to many join on the phone number
var q3 = from c in contacts
orderby c.LastName
select new
{
LastName = c.LastName,
Calls = calls_lookup[c.Phone]
};
foreach (var contact in q3)
{
Console.WriteLine("Last name: {0}", contact.LastName);
foreach (var call in contact.Calls)
Console.WriteLine(" – {0} call on {1} for {2}min.",
call.Incoming ? "Incoming" : "Outgoing",
call.When,
call.Duration);
}
}
Console output (Execution time: 5ms):
[Hide/Show]
Last name: Deane
Last name: Gauwain
Last name: Gottshall
– Incoming call on 8/7/2006 1:47:00 PM for 3min.
– Outgoing call on 8/7/2006 1:12:00 PM for 15min.
– Incoming call on 8/7/2006 8:12:00 AM for 2min.
– Incoming call on 7/12/2006 8:12:00 AM for 5min.
– Incoming call on 7/7/2006 1:47:00 PM for 21min.
– Outgoing call on 6/7/2006 1:12:00 PM for 10min.
Last name: Hazelgrove
– Incoming call on 8/7/2006 9:23:00 AM for 15min.
– Incoming call on 6/14/2006 9:23:00 AM for 12min.
Last name: Kagel
– Outgoing call on 8/8/2006 10:10:00 AM for 3min.
– Outgoing call on 8/7/2006 8:34:00 PM for 1min.
– Incoming call on 8/7/2006 11:15:00 AM for 4min.
– Outgoing call on 7/7/2006 8:34:00 PM for 7min.
– Outgoing call on 6/8/2006 10:10:00 AM for 2min.
– Incoming call on 6/7/2006 11:15:00 AM for 9min.
Last name: Kamph
– Incoming call on 8/8/2006 5:12:00 PM for 20min.
– Outgoing call on 8/7/2006 10:05:00 AM for 1min.
– Outgoing call on 7/9/2006 10:05:00 AM for 10min.
– Incoming call on 6/8/2006 5:12:00 PM for 24min.
Last name: Lard
– Incoming call on 8/8/2006 3:23:00 PM for 6min.
– Incoming call on 5/8/2006 3:23:00 PM for 16min.
Last name: Reifsteck
Last name: Valdes
– Incoming call on 8/8/2006 2:37:00 PM for 7min.
– Outgoing call on 8/8/2006 2:00:00 PM for 3min.
– Incoming call on 7/8/2006 2:37:00 PM for 13min.
– Outgoing call on 7/8/2006 2:00:00 PM for 32min.
Last name: Zeeman
– Outgoing call on 8/8/2006 10:40:00 AM for 23min.
– Outgoing call on 8/7/2006 10:35:00 AM for 2min.
– Outgoing call on 7/5/2006 10:35:00 AM for 22min.
– Outgoing call on 6/8/2006 10:40:00 AM for 3min.
Top
EditElement Operators
EditListing 5-15 : DefaultIfEmpty operator
This sample demonstrates how to use the DefaultIfEmpty operator.
public void Listing_5_15_DefaultIfEmptyOperator()
{
var nums = new int[] { 1, 2, 3, 4, 5 };
var empty = new int[] { };
// returns 1, because the array isn't empty
Console.WriteLine("nums.DefaultIfEmpty() = {0}",
nums.DefaultIfEmpty().First());
// returns default(int) in an IEnumerable<int>
Console.WriteLine("empty.DefaultIfEmpty() = {0}",
empty.DefaultIfEmpty().First());
// returns 100. The array is empty, but an explicit
// default value is passed in as an argument.
Console.WriteLine("empty.DefaultIfEmpty(100) = {0}",
empty.DefaultIfEmpty(100).First());
}
Console output (Execution time: 4ms):
[Hide/Show]
nums.DefaultIfEmpty() = 1
empty.DefaultIfEmpty() = 0
empty.DefaultIfEmpty(100) = 100
Top
EditListing 5-16 : ElementAt and ElementAtOrDefault operator
This sample demonstrates how to use the ElementAt and ElementAtOrDefault operators.
public void Listing_5_16_ElementAtOperator()
{
var nums = new int[] { 1, 2, 3, 4, 5 };
// get the third element (zero–based index position of 2)
var third = nums.ElementAt(2);
// ERROR: System.ArgumentOutOfRangeException, if the
// index is < 0 or beyond the end of the sequence.
// var error = nums.ElementAt(100);
// returns an default(T), 0 for a value int type.
var no_error = nums.ElementAtOrDefault(100);
Console.WriteLine("nums.ElementAt(2) = {0}",
nums.ElementAt(2));
Console.WriteLine("nums.ElementAtOrDefault(100) = {0}",
nums.ElementAtOrDefault(100));
}
Console output (Execution time: 1ms):
[Hide/Show]
nums.ElementAt(2) = 3
nums.ElementAtOrDefault(100) = 0
Top
EditListing 5-17 : First and FirstOrDefault operator
This sample demonstrates how to use the First and FirstOrDefault operators.
public void Listing_5_17_FirstOperator()
{
var nums = new int[] { 1, 2, 3, 4, 5 };
var empty = new int[] { };
// get the first element
var first = nums.First();
// get the first element > 2
var third = nums.First(i => i > 2);
// ERROR: System.InvalidOperationException
// var error = empty.First();
// returns an default(T), 0 for a value int type.
var no_error = empty.FirstOrDefault();
// ERROR: System.InvalidOperationException.
// No value > 10 in this sequence.
// var error = nums.First(i => i > 10);
// No value > 10 in this sequence. default(T) returned.
var no_error2 = nums.FirstOrDefault(i => i > 10);
Console.WriteLine("first = {0}, third = {1}",
first, third);
Console.WriteLine("no_error = {0}, no_error2 = {1}",
no_error, no_error2);
}
Console output (Execution time: 2ms):
[Hide/Show]
first = 1, third = 3
no_error = 0, no_error2 = 0
Top
EditListing 5-18 : Last and LastOrDefault operator
This sample demonstrates how to use the Last and LastOrDefault operators.
public void Listing_5_18_LastOperator()
{
var nums = new int[] { 1, 2, 3, 4, 5 };
var empty = new int[] { };
// get the last element
var last = nums.Last();
// get the last element < 4
var third = nums.Last(i => i < 4);
// ERROR: System.InvalidOperationException
// var error = empty.Last();
// returns an default(T), 0 for a value int type.
var no_error = empty.LastOrDefault();
// ERROR: System.InvalidOperationException.
// No value > 10 in this sequence.
// var error = nums.Last(i => i > 10);
// No value > 10 in this sequence. default(T) returned.
var no_error2 = nums.LastOrDefault(i => i > 10);
Console.WriteLine("last = {0}, third = {1}",
last, third);
Console.WriteLine("no_error = {0}, no_error2 = {1}",
no_error, no_error2);
}
Console output (Execution time: 5ms):
[Hide/Show]
last = 5, third = 3
no_error = 0, no_error2 = 0
Top
EditListing 5-19 : Single and SingleOrDefault operator
This sample demonstrates how to use the Single and SingleOrDefault operators.
public void Listing_5_19_SingleOperator()
{
var single = new int[] { 5 };
var nums = new int[] { 1, 2, 3, 4, 5 };
var empty = new int[] { };
// get the single element
var five = single.Single();
// get the last element < 4
var third = nums.Single(i => i == 3);
// ERROR: System.InvalidOperationException
// more than one element in the sequence nums.
// var error = nums.Single();
// var error = nums.SingleOrDefault();
// returns an default(T), 0 for a value int type.
var no_error = empty.SingleOrDefault();
// ERROR: System.InvalidOperationException.
// No value == 10 in this sequence.
// var error = nums.Single(i => i == 10);
// No value == 10 in this sequence. default(T) returned.
var no_error2 = nums.SingleOrDefault(i => i == 10);
Console.WriteLine("five = {0}, third = {1}",
five, third);
Console.WriteLine(
"no_error = {0}, no_error2 = {1}",
no_error, no_error2);
}
Console output (Execution time: 5ms):
[Hide/Show]
five = 5, third = 3
no_error = 0, no_error2 = 0
Top
EditEquality Operators
EditListing 5-20 : SquenceEqual operator
This sample demonstrates how to use the SequenceEqual operator.
public void Listing_5_20_SequenceEqualOperator()
{
var n1 = new string[] { "peter", "paul", "mary" };
var n2 = new string[] { "paul", "peter", "mary" };
var n3 = new string[] { "PETER", "PAUL", "MARY" };
// order dependent
bool n1n2 = n1.SequenceEqual(n2);
// case–sensitive using the default comparer
bool n1n3 = n1.SequenceEqual(n3);
// passing in a comparer – this time using the
// built–in StringComparer static instances.
bool n1n3_2 = n1.SequenceEqual(
n3, StringComparer.CurrentCultureIgnoreCase);
Console.WriteLine("n1n2 = {0}, n1n3 = {1}, n1n3_2 = {2}",
n1n2, n1n3, n1n3_2);
}
Console output (Execution time: 0ms):
[Hide/Show]
n1n2 = False, n1n3 = False, n1n3_2 = True
Top
EditGeneration Operators
EditListing 5 : Empty
This sample demonstrates how to use the empty operator.
public void Listing_5_EmptyOperator()
{
var x = MyEmpty<int>();
Console.WriteLine("x.Count = {0}", x.Count());
var y = Enumerable.Empty<int>();
Console.WriteLine("y.Count = {0}", y.Count());
}
Console output (Execution time: 1ms):
[Hide/Show]
Top
EditListing 5-21 : Range
This sample demonstrates how to use the Range operator.
public void Listing_5_21_RangeOperator()
{
var months = Enumerable.Range(1, 12);
foreach (var item in months)
Console.Write(item + " ");
// useful for databinding int sequences to combo–boxes
ComboBox yearsCombo = new ComboBox();
yearsCombo.DataSource =
Enumerable.Range(1900, 111).Reverse().ToList();
Form form = new Form();
form.Controls.Add(yearsCombo);
form.ShowDialog();
}
Console output (Execution time: 7209ms):
[Hide/Show]
1 2 3 4 5 6 7 8 9 10 11 12
Top
EditListing 5-22 : Range indexing bitmap pixels
This sample demonstrates how to use the Range operator to iterate the pixels in a bitmap image.
public void Listing_5_22_RangeOperatorWithBitmap()
{
// example of using range to address x,y locations in a bitmap
string filename = Path.Combine(
Environment.CurrentDirectory, @"data\4pixeltest.bmp");
Bitmap bmp = (Bitmap)Image.FromFile(filename);
var q = from x in Enumerable.Range(0, bmp.Width)
from y in Enumerable.Range(0, bmp.Height)
let pixel = bmp.GetPixel(x, y)
let lum = (byte)((0.2126 * pixel.R)
+ (0.7152 * pixel.G)
+ (0.0722 * pixel.B))
select new { x, y, lum };
foreach (var item in q)
{
Console.WriteLine("{0},{1} – {2}",
item.x, item.y, item.lum);
}
}
Console output (Execution time: 15ms):
[Hide/Show]
0,0 – 220
0,1 – 73
1,0 – 101
1,1 – 144
Top
EditListing 5-23 : Repeat Operator
This sample demonstrates how to use the Repeat operator.
public void Listing_5_23_RepeatOperator()
{
int[] i = Enumerable.Repeat(–1, 10).ToArray();
string[] s = Enumerable.Repeat("No data", 3).ToArray();
// WARNING! Reference types will all point to the same bitmap
// instance. Use care to determine if this is the desired behavior.
Bitmap[] b1 = Enumerable.Repeat(new Bitmap(5,5), 5).ToArray();
// Instead – use repeat as a looping construct,
// and project using a select operator. You will
// have 5 different Bitmap instances in the array.
Bitmap[] b2 = Enumerable.Repeat(0, 5)
.Select(x => new Bitmap(5, 5)).ToArray();
}
Top
EditMerging Operators
EditListing 5-24 : Zip Operator
This sample demonstrates how to use the Zip operator.
public void Listing_5_24_ZipOperator()
{
var letters = new string[] { "A", "B", "C", "D", "E" };
var numbers = new int[] { 1, 2, 3 };
var q = letters.Zip(numbers, (s, i) => s + i.ToString());
foreach (var s in q)
Console.WriteLine(s);
}
Console output (Execution time: 12ms):
[Hide/Show]
Top
EditPaging Operators
EditListing 5-25 : Skip/Take Operator
This sample demonstrates how to use the Skip and Take operators for paging.
public void Listing_5_25_SkipTakeOperator()
{
int[] nums = Enumerable.Range(1, 50).ToArray();
int page = 3;
int pageSize = 10;
var q = nums
.Skip( (page–1) * pageSize )
.Take( pageSize );
foreach (var i in q)
Console.Write(i + " ");
// custom extension method for paging
var q1 = nums.Page(3, 10);
}
Console output (Execution time: 16ms):
[Hide/Show]
21 22 23 24 25 26 27 28 29 30
Top
EditListing 5-26 : Page Operator
This sample demonstrates how to use a custom operator for paging.
public void Listing_5_26_PageOperator()
{
int[] nums = Enumerable.Range(1, 50).ToArray();
// custom extension method for paging
var q = nums.Page(3, 10);
foreach (var i in q)
Console.Write(i + " ");
}
Console output (Execution time: 0ms):
[Hide/Show]
21 22 23 24 25 26 27 28 29 30
Top
EditListing 5-27 : SkipWhile Operator
This sample demonstrates how to use the SkipWhile operator.
public void Listing_5_27_SkipWhileTakeWhileOperator()
{
string sampleString =
@"# comment line 1
- comment line 2
Data line 1
Data line 2
This line is ignored
";
var q = sampleString.Split('\n')
.SkipWhile(line => line.StartsWith("#"))
.TakeWhile(line => !string.IsNullOrEmpty(line.Trim()));
foreach (var s in q)
Console.WriteLine(s);
}
Console output (Execution time: 2ms):
[Hide/Show]
Top
EditQuantifier Operators
EditListing 5-28 : All Operator
This sample demonstrates how to use the All Operator
public void Listing_5_28_All()
{
var evens = new int[] { 2, 4, 6, 8, 10 };
var odds = new int[] { 1, 3, 5, 7, 9 };
var nums = Enumerable.Range(1, 10);
// equivalent LINQ query
bool b1 = evens.All(i => i % 2 == 0);
bool b2 =
evens.Count() == evens.Where(i => i % 2 == 0).Count();
Console.WriteLine("All even? evens: {0}, odds: {1}, nums: {2}",
evens.All(i=> i%2 == 0),
odds.All(i => i%2 == 0),
nums.All(i => i%2 == 0)
);
}
Console output (Execution time: 5ms):
[Hide/Show]
All even? evens: True, odds: False, nums: False
Top
EditListing 5-29 : All Operator with predicate over data
This sample demonstrates how to use the All Operator with a predicate over data
public void Listing_5_29_AllPredicateData()
{
var contacts = Contact.SampleData();
bool allOver21 = contacts.All(
c => c.DateOfBirth.AddYears(21) < DateTime.Now);
bool allContactsHaveContactData = contacts.All(
c => string.IsNullOrEmpty(c.Phone) == false &&
string.IsNullOrEmpty(c.Email) == false);
Console.WriteLine("Are all contacts over 21 years old? {0}",
allOver21);
Console.WriteLine("Do all contacts have email and phone? {0}",
allContactsHaveContactData);
}
Console output (Execution time: 2ms):
[Hide/Show]
Are all contacts over 21 years old? True
Do all contacts have email and phone? True
Top
EditListing 5-30 : Any Operator
This sample demonstrates how to use the Any Operator
public void Listing_5_30_Any()
{
var empty = Enumerable.Empty<int>();
var one = new int[] { 1 };
var many = Enumerable.Range(1,5);
// LINQ equivalent
bool b = one.Count() > 0;
Console.WriteLine("Empty: {0}, One: {1}, Many: {2}",
empty.Any(), one.Any(), many.Any());
}
Console output (Execution time: 1ms):
[Hide/Show]
Empty: False, One: True, Many: True
Top
EditListing 5-31 : Any Operator with predicate
This sample demonstrates how to use the Any Operator with a predicate
public void Listing_5_31_AnyPredicate()
{
string[] animals = new string[] { "Koala", "Kangaroo",
"Spider", "Wombat", "Snake", "Emu", "Shark",
"Sting–Ray", "Jellyfish" };
// LINQ Equivalent
bool b = animals.Where(a => a.Contains("fish")).Count() > 0;
bool anyFish = animals.Any(a => a.Contains("fish"));
bool anyCats = animals.Any(a => a.Contains("cat"));
Console.WriteLine("Any fish? {0}, Any cats? {1}",
anyFish, anyCats);
}
Console output (Execution time: 2ms):
[Hide/Show]
Any fish? True, Any cats? False
Top
EditListing 5-32 : Any Operator with predicate over data
This sample demonstrates how to use the Any Operator with a predicate over data
public void Listing_5_32_AnyPredicateData()
{
var contacts = Contact.SampleData();
bool anyUnder21 = contacts.Any(
c => c.DateOfBirth.AddYears(21) > DateTime.Now);
bool anyMissingContactData = contacts.Any(
c => string.IsNullOrEmpty(c.Phone) ||
string.IsNullOrEmpty(c.Email));
Console.WriteLine("Are any contacts under 21 years old? {0}",
anyUnder21);
Console.WriteLine("Are any records without email or phone? {0}",
anyMissingContactData);
}
Console output (Execution time: 1ms):
[Hide/Show]
Are any contacts under 21 years old? False
Are any records without email or phone? False
Top
EditListing 5-33 : Contains Operator
This sample demonstrates how to use the Contains Operator
public void Listing_5_33_Contains()
{
string[] names = new string[] { "peter", "paul", "mary" };
bool b1 = names.Contains("PETER");
bool b2 = names.Contains("peter");
// Custom comparers or the built–in comparers can be used.
bool b3 = names.Contains(
"PETER", StringComparer.CurrentCultureIgnoreCase);
Console.WriteLine("PETER: {0}, peter: {1}, PETER: {2}",
b1, b2, b3);
}
Console output (Execution time: 0ms):
[Hide/Show]
PETER: False, peter: True, PETER: True
Top
EditListing 5-34 : Contains Operator on List
This sample demonstrates how to use the Contains Operator on List which already has a Contains instance method
public void Listing_5_34_ContainsList()
{
// List<T> already has an instance method called "Contains"
// The instance method doesn't have an overload that
// supports EqualityComparer's, and the Contains
// extension method can be used for this call.
List<string> list =
new List<string> { "peter", "paul", "mary" };
// will use the List<T>.Contains method
bool b4 = list.Contains("PETER");
// will force use of the Contains Extension Method
bool b5 = list.Contains<string>("PETER");
// or better still, just call the Extension Method
bool b5a = Enumerable.Contains(list, "PETER");
// will use the Contains Extension method because
// the List<T>.Contains has no overload taking
// an IEqualityComparer
bool b6 = list.Contains(
"PETER", StringComparer.CurrentCultureIgnoreCase);
Console.WriteLine(
"Instance: {0}, Extension: {1}, With Comparer: {2}",
b4, b5, b6);
}
Console output (Execution time: 1ms):
[Hide/Show]
Instance: False, Extension: False, With Comparer: True
Top