public static IEnumerable <Bird> Search(this IEnumerable <Bird> source, BirdSearch search) { return(source .Where(s => string.IsNullOrEmpty(search.CommonName) || s.CommonName.Contains(search.CommonName)) .Where(s => string.IsNullOrEmpty(search.Country) || s.Habitats.Any(h => h.Country.Contains(search.Country))) .Where(s => search.Colors.Any(c => s.PrimaryColor.Equals(c) || s.SecondaryColor.Equals(c)) || search.Colors.Join(s.TertiaryColors, sc => sc, tc => tc, (sc, tc) => sc).Any()) .Skip(search.Page * search.PageSize) .Take(search.PageSize)); }
static void TestBirds() { var birds = BirdRepository.LoadBirds(); var sightings = birds.SelectMany(b => b.Sightings); var avgS = birds.Select(b => b.Sightings.Count()).Average(); var sightingsByCountry = sightings .GroupBy(s => s.Place.Country) .Select(g => new { Country = g.Key, Sightings = g.Count() }); var birdCountByStatus = birds .Where(b => b.ConservationStatus != "LeastConcern" && b.ConservationStatus != "NearThreatened") .GroupBy(b => b.ConservationStatus) .Select(selector: g => new { Status = g.Key, Count = g.Count(), Sightings = g.Sum(b => b.Sightings.Count) }); var statuses = birds .Select(b => b.ConservationStatus) .Where(s => s != "LeastConcern" && s != "NearThreatened") .Distinct(); var endangeredSightings = birds .Join(statuses, b => b.ConservationStatus, s => s, (b, s) => new { Status = s, Sigthings = b.Sightings }) .GroupBy(a => a.Status) .Select(g => new { Status = g.Key, Sightings = g.Sum(selector: s => s.Sigthings.Count) }); var importedBirds = BirdRepository.LoadImportedBirds(); var matchingBirds = birds.Intersect(importedBirds, new BirdComparer()); // Perform outer join to get elements that exist in one enumerable and not in the other var newBirds = importedBirds.GroupJoin(birds, ib => ib.CommonName, b => b.CommonName, (ib, b) => new { ImportedBird = ib, Birds = b }) // Variant 1: flatten the grouping first, providing default value for elements with no matches, then filter records //.SelectMany(gb => gb.Birds.DefaultIfEmpty(), (gb, b) => new { ImportedBird = gb.ImportedBird, Bird = b }) //.Where(a => a.Bird == null) // Variant 2: filter the grouping directly - my option .Where(a => a.Birds.Count() == 0) .Select(a => a.ImportedBird) .ToList(); var searchParams = new BirdSearch { Country = "United States", Colors = new List <string> { "White", "Brown", "Black" }, Page = 0, PageSize = 5 }; var foundBirds = birds.Search(searchParams); }