using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Operators
{
    class Program
    {
        static void Main(string[] args)
        {
            Examples18_19.IndexedWhere();
            Examples18_19.UseOfType();
            Examples20_25.IndexedSelect();
            Examples20_25.IndexedSelectAfterWhere();
            Examples20_25.IndexedSelectBeforeWhere();
            Examples20_25.OverFetching();
            Examples20_25.SelectToAnonymousType();
            Examples20_25.MappingItems();
            Examples26_30.SelectManyQueryExpression();
            Examples26_30.SelectManyDirect();
            Examples26_30.FlattenArray();
            Examples26_30.FlattenArrayDirect();
            Examples31_34.OrderByQueryExpression();
            Console.WriteLine();
            Examples31_34.BadMultipleOrdering();
            Console.WriteLine();
            Examples31_34.MultipleOrderingQueryExpression();
            Console.WriteLine();
            Examples31_34.MultipleOrderingDirect();
            Examples35_38.SingleOperator();
            Examples35_38.SelectFirstFromOrderedCollection();
            Examples35_38.UsingElementAtTheSlowWay();
            Examples39_46.GetAverage();
            Examples39_46.GetMaxWithProjection();
            Examples39_46.SumAndAggregate();
            Examples39_46.MaxWithAggregate();
            Examples39_46.AverageWithAggregate();
            Examples39_46.CalcluateBoundingBoxWithAggregate();
            Examples39_46.ExplicitExpansionOfBoundingBoxAggregation();
            Examples47_48.ShowDistinctCategories();
            Examples47_48.CombineWithZip();
            Examples49_57.GroupingQueryExpression();
            Examples49_57.UseGroupOperatorDirectly();
            Examples49_57.GroupWithItemProjection();
            Examples49_57.DirectGroupWithItemProjection();
            Examples49_57.GroupQueryWithGroupProjection();
            Examples49_57.DirectGroupWithGroupProjection();
            Examples49_57.GroupWithKeyAndGroupProjections();
            Examples49_57.GroupWithKeyItemAndGroupProjections();
            Examples49_57.CompositeGroupKey();
            Examples58_62.QueryWithJoin();
            Examples58_62.DirectJoin();
            Examples58_62.GroupedJoin();
            Examples58_62.DirectGroupedJoin();
            Examples63_65.FailingSequenceCast();
            Examples63_65.SequenceCast();
            Examples63_65.CreateLookup();
        }
    }

    public static class ShowExtensions
    {
        public static void Show(this IEnumerable<Course> courses)
        {
            foreach (Course c in courses)
            {
                Console.WriteLine("{0}{1}: {2}", c.Category, c.Number, c.Title);
            }
        }

        public static void Show<T>(this IEnumerable<T> items)
        {
            foreach (T item in items)
            {
                Console.WriteLine(item.ToString());
            }
        }
    }
}
