namespace ConsoleTask.Linq
{
public class Racer : IComparable<Racer>, IFormattable
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Wins { get; set; }
public string Country { get; set; }
public int Starts { get; set; }
public IEnumerable<string> Cars { get; set; }
public IEnumerable<int> Years { get; set; }
public Racer(string firstName, string lastName, string country, int starts, int wins)
: this(firstName, lastName, country, starts, wins, null, null)
{
}
public Racer(string firstName, string lastName, string country, int starts, int wins, IEnumerable<int> years, IEnumerable<string> cars)
{
FirstName = firstName;
LastName = lastName;
Wins = wins;
Country = country;
Starts = starts;
Cars = cars;
Years = years;
}
public int CompareTo(Racer other) => LastName.CompareTo(other?.LastName);
public override string ToString() => $"{FirstName} {LastName}";
public string ToString(string format) => ToString(format, null);
public string ToString(string format, IFormatProvider formatProvider)
{
switch (format)
{
case null:
case "N":
return ToString();
case "F":
return FirstName;
case "L":
return LastName;
case "C":
return Country;
case "S":
return Starts.ToString();
case "W":
return Wins.ToString();
case "A":
return $"{FirstName} {LastName}, {Country};starts:{Starts},wins:{Wins}";
default:
throw new FormatException($"Format {format} not supported");
}
}
}
}
namespace ConsoleTask.Linq
{
public class Team
{
public string Name { get; set; }
public IEnumerable<int> Years { get; set; }
public Team(string name, params int[] years)
{
Name = name;
Years = years != null ? new List<int>(years) : new List<int>();
}
}
}
namespace ConsoleTask.Linq
{
public class Formulal
{
private static List<Racer> _racers;
public static IList<Racer> GetChampions()
{
if (_racers == null)
{
_racers = new List<Racer>(40);
_racers.Add(new Racer("Nino", "Farina", "Italy", 33, 5, new int[] { 1950 }, new string[] { "Alfa Romeo" }));
_racers.Add(new Racer("Alberto", "Ascari", "Italy", 32, 10, new int[] { 1952, 1953 }, new string[] { "Ferrari" }));
_racers.Add(new Racer("Juan Manuel", "Fangio", "Argentina", 51, 24, new int[] { 1951, 1954, 1955, 1956, 1957, 1958, 1961 },
new string[] { "Alfa Romeo", "Maserati", "Mercedes", "Ferrari" }));
_racers.Add(new Racer("Mike", "Hawthorn", "UK", 45, 3, new int[] { 1958 }, new string[] { "Ferrari", "McLaren" }));
_racers.Add(new Racer("Phil", "Hill", "USA", 48, 3, new int[] { 1961 }, new string[] { "Ferrari" }));
_racers.Add(new Racer("John", "Surtees", "UK", 111, 6, new int[] { 1964 }, new string[] { "Ferrari" }));
_racers.Add(new Racer("Jim", "Clark", "UK", 72, 25, new int[] { 1963, 1965 }, new string[] { "Lotus" }));
_racers.Add(new Racer("Jack", "Brabham", "Australia", 125, 14, new int[] { 1959, 1960, 1966 }, new string[] { "Cooper", "Brabham" }));
_racers.Add(new Racer("Denny", "Hulme", "New Zealand", 112, 8, new int[] { 1967 }, new string[] { "Brabham" }));
_racers.Add(new Racer("Graham", "Hill", "UK", 196, 14, new int[] { 1962, 1968 }, new string[] { "BRM", "Lotus" }));
_racers.Add(new Racer("Jochen", "Rindt", "Austria", 60, 6, new int[] { 1970 }, new string[] { "Lotus" }));
_racers.Add(new Racer("Jackie", "Stewart", "UK", 99, 27, new int[] { 1969, 1971, 1973 }, new string[] { "Matra", "Tyrrell" }));
}
return _racers;
}
private static List<Team> _teams;
public static IList<Team> GetContructorChampions()
{
if (_teams == null)
{
_teams = new List<Team>()
{
new Team("Vanwall",1958),
new Team("Cooper",1959,1960),
new Team("Ferrari",1961,1964,1975,1976,1977,1979,1982,1983,1999,2000,2001,2002,2003,2004,2007,2008),
new Team("BRM",1962),
new Team("Lotus",1963,1965,1968,1970,1972,1973,1978),
new Team("Brabham",1966,1967),
new Team("Matra",1969),
new Team("Tyrrell",1971),
new Team("McLaren",1974,1984,1985,1988,1989,1990,1991,1998),
new Team("Williams",1980,1981,1986,1987,1992,1993,1994,1996,1997),
new Team("Benetton",1995),
new Team("Renault",2005,2006),
new Team("Brawn GP",2009),
new Team("Red Bull Racing",2010,2011,2012,2013),
new Team("Mercedes",2014,2015)
};
}
return _teams;
}
}
}
namespace ConsoleTask.Linq
{
public class Championship
{
public int Year { get; set; }
public string First { get; set; }
public string Second { get; set; }
public string Third { get; set; }
}
public class RacerInfo
{
public int Year { get; set; }
public int Position { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class TestLinq
{
public static void TestByLinqTwentyFour()
{
const int arraySize = 50000000;
var r = new Random();
var query = Enumerable.Range(0, arraySize).Select(x => r.Next(140)).ToList();
var cts = new CancellationTokenSource();
Task.Run(() =>
{
try
{
var res = (from x in query.AsParallel().WithCancellation(cts.Token)
where Math.Log(x) < 4
select x).Average();
WriteLine($"query finished,sum:{res}");
}
catch (Exception ex)
{
WriteLine(ex.Message);
}
});
WriteLine("query started");
Write("cancel? ");
string input = ReadLine();
if (input.ToLower().Equals("y"))
{
cts.Cancel();
}
}
public static void TestByLinqTwentyThree()
{
const int arraySize = 50000000;
var r = new Random();
var query = Enumerable.Range(0, arraySize).Select(x => r.Next(140)).ToList();
WriteLine(query.Count());
for (int i = 0; i < 50; i++)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
if (i < 10)
{
var res = (from x in query
where Math.Log(x) < 4
select x).Average();
}
else if (i < 20)
{
var res = (from x in query.AsParallel().WithDegreeOfParallelism(6)
where Math.Log(x) < 4
select x).Average();
}
else if (i < 30)
{
var res = (from x in query.AsParallel().WithDegreeOfParallelism(12)
where Math.Log(x) < 4
select x).Average();
}
else if (i < 40)
{
var res = (from x in query.AsParallel()
where Math.Log(x) < 4
select x).Average();
}
else
{
var result = (from x in Partitioner.Create(query, true).AsParallel()
where Math.Log(x) < 4
select x).Average();
}
stopwatch.Stop();
WriteLine("毫秒数:" + stopwatch.Elapsed.Milliseconds);
}
}
public static void TestByLinqTwentyTwo()
{
var list = new ArrayList(Formulal.GetChampions() as ICollection);
var query = from r in list.Cast<Racer>()
where r.Country == "USA"
orderby r.Wins descending
select r;
foreach (var item in query)
{
WriteLine($"{item:A}");
}
}
public static void TestByLinqTwentyOne()
{
var query = (from r in Formulal.GetChampions()
from c in r.Cars
select new
{
Car = c,
Racer = r
}).ToLookup(cr => cr.Car, cr => cr.Racer);
if (query.Contains("Ferrari"))
{
foreach (var item in query["Ferrari"])
{
WriteLine(item);
}
}
}
public static void TestByLinqTwenty()
{
var numPlus = Enumerable.Range(1, 100).Aggregate((x, y) => x + y);
WriteLine($"累计和:{numPlus}");
var numReduce = Enumerable.Range(2, 4).Aggregate(10, (x, y) => x * y);
WriteLine($"累计阶乘:{numReduce}");
string[] str = { "张三", "李四", "王五", "赵六", "王二麻子" };
var res = str.Aggregate((value, next) => value + "爱" + next);
WriteLine(res);
}
public static void TestByLinqNineteen()
{
var query = (from c in
from r in Formulal.GetChampions()
group r by r.Country into c
select new
{
Country = c.Key,
Wins = (from r1 in c select r1.Wins).Sum()
}
orderby c.Wins ascending, c.Country
select c).TakeWhile(c => c.Wins < 14);
foreach (var item in query)
{
Console.WriteLine($"{item.Country} {item.Wins}");
}
}
public static void TestByLinqEighteen()
{
int pageSize = 5;
int total = Formulal.GetChampions().Count();
int numberPages = (int)Math.Ceiling(total / (double)pageSize);
for (int i = 0; i < numberPages; i++)
{
WriteLine($"Page {i}");
var query = (from r in Formulal.GetChampions()
orderby r.LastName, r.FirstName
select r.FirstName + " " + r.LastName)
.Skip(i * pageSize).Take(pageSize);
foreach (var item in query)
{
WriteLine(item);
}
WriteLine();
}
}
public static void TestByLinqSeventeen()
{
var query = from r in Formulal.GetChampions()
where r.Country == "Italy"
orderby r.Wins descending
select r;
foreach (var item in query)
{
WriteLine($"{item:A}");
}
WriteLine();
var extendQuery = Formulal.GetChampions().Where(r => r.Country == "Italy").OrderByDescending(r => r.Wins).Reverse();
foreach (var item in extendQuery)
{
WriteLine($"{item:A}");
}
}
public static void TestByLinqSixteen()
{
var racerNames = from r in Formulal.GetChampions()
where r.Country == "Italy"
orderby r.Wins descending
select new
{
Name = r.FirstName + " " + r.LastName
};
var racerNamesAndStarts = from r in Formulal.GetChampions()
where r.Country == "Argentina"
orderby r.Wins descending
select new
{
r.LastName,
r.Starts
};
var query = racerNames.Zip(racerNamesAndStarts, (first, second) => first.Name + ",starts:" + second.Starts);
foreach (var item in query)
{
WriteLine(item);
}
}
public static void TestByLinqFifteen()
{
IEnumerable<Racer> racersByCar(string car) => from r in Formulal.GetChampions()
from c in r.Cars
where c == car
orderby r.LastName
select r;
WriteLine();
foreach (var item in racersByCar("Ferrari").Intersect(racersByCar("McLaren")))
{
WriteLine(item);
}
}
private static List<Championship> championships;
public static void TestByLinqFourteen()
{
IEnumerable<Championship> GetChampionships()
{
if (championships == null)
{
championships = new List<Championship>();
championships.Add(new Championship
{
Year = 1950,
First = "Nino Farina",
Second = "Juan Manuel Fangio",
Third = "Luigi Fagioli"
});
championships.Add(new Championship
{
Year = 1951,
First = "Juan Manuel Fangio",
Second = "Alberto Ascari",
Third = "Froilan Gonzalez"
});
}
return championships;
}
string FirstName(string name)
{
int ix = name.LastIndexOf(' ');
return name.Substring(0, ix);
}
string LastName(string name)
{
int ix = name.LastIndexOf(' ');
return name.Substring(ix + 1);
}
var racers = GetChampionships()
.SelectMany(cs => new List<RacerInfo>()
{
new RacerInfo{
Year =cs.Year,
Position = 1,
FirstName =FirstName(cs.First),
LastName=LastName(cs.First)
},
new RacerInfo{
Year =cs.Year,
Position = 2,
FirstName =FirstName(cs.Second),
LastName=LastName(cs.Second)
},
new RacerInfo{
Year =cs.Year,
Position = 3,
FirstName =FirstName(cs.Third),
LastName=LastName(cs.Third)
}
});
var query = from r in Formulal.GetChampions()
join r2 in racers on
new { r.FirstName, r.LastName }
equals
new { r2.FirstName, r2.LastName }
into YearResults
select new
{
r.FirstName,
r.LastName,
r.Wins,
r.Starts,
Results = YearResults
};
foreach (var item in query)
{
WriteLine($"{item.FirstName} {item.LastName}");
foreach (var m in item.Results)
{
WriteLine($"{m.Year} {m.Position}");
}
}
}
public static void TestByLinqThirteen()
{
var racers = from r in Formulal.GetChampions()
from y in r.Years
select new
{
Year = y,
Name = r.FirstName + " " + r.LastName
};
var teams = from t in Formulal.GetContructorChampions()
from y in t.Years
select new
{
Year = y,
t.Name
};
var query = (from r in racers
join t in teams on r.Year equals t.Year into rt
from t in rt.DefaultIfEmpty()
orderby r.Year
select new
{
r.Year,
Champion = r.Name,
Constructor = t == null ? "no constructor championship" : t.Name
}).Take(10);
foreach (var item in query)
{
WriteLine($"{item.Year}:{item.Champion,-20} {item.Constructor}");
}
}
public static void TestByLinqTwelve()
{
var racers = from r in Formulal.GetChampions()
from y in r.Years
select new
{
Year = y,
Name = r.FirstName + " " + r.LastName
};
var teams = from t in Formulal.GetContructorChampions()
from y in t.Years
select new
{
Year = y,
t.Name
};
var query = from r in racers
join t in teams on r.Year equals t.Year
select new
{
r.Year,
Champion = r.Name,
Constructor = t.Name
};
foreach (var item in query)
{
WriteLine($"{item.Year}:{item.Champion,-20} {item.Constructor}");
}
WriteLine();
var extendQuery = racers.Join(
teams,
r => r.Year,
t => t.Year,
(r, t) => new
{
r.Year,
Champion = r.Name,
Constructor = t.Name
});
foreach (var item in extendQuery)
{
WriteLine($"{item.Year}:{item.Champion,-20} {item.Constructor}");
}
WriteLine();
var extendQueryGroupJoin = teams.GroupJoin(racers, t => t.Year, r => r.Year, (t, r) => new { t.Year, Racers = r });
foreach (var item in extendQueryGroupJoin)
{
WriteLine($"{item.Year}");
foreach (var m in item.Racers)
{
Write($"{m:F},");
}
WriteLine();
}
}
public static void TestByLinqEleven()
{
var query = from r in Formulal.GetChampions()
group r by r.Country into g
let Con = g.Count()
orderby Con descending, g.Key
where Con >= 2
select new
{
Country = g.Key,
Count = Con,
Racers = from r1 in g orderby r1.LastName select r1.FirstName + " " + r1.LastName
};
string json = JsonConvert.SerializeObject(query);
foreach (var item in query)
{
WriteLine($"{item.Country:-10} {item.Count}");
foreach (var m in item.Racers)
{
Write($"{m};");
}
WriteLine();
}
}
public static void TestByLinqTen()
{
var query = from r in Formulal.GetChampions()
group r by r.Country into g
let count = g.Count()
orderby count descending, g.Key
where count >= 2
select new
{
Country = g.Key,
Count = count
};
foreach (var item in query)
{
WriteLine($"{item:A}");
}
WriteLine();
var extendQuery = Formulal.GetChampions()
.GroupBy(r => r.Country)
.Select(g => new { Group = g, Con = g.Count() })
.OrderByDescending(g => g.Con)
.ThenBy(g => g.Group.Key)
.Where(g => g.Con >= 2)
.Select(g => new
{
Country = g.Group.Key,
Count = g.Con
});
foreach (var item in extendQuery)
{
WriteLine($"{item:A}");
}
}
public static void TestByLinqNine()
{
var query = from r in Formulal.GetChampions()
group r by r.Country into g
orderby g.Count() descending, g.Key
where g.Count() >= 2
select new
{
Country = g.Key,
Count = g.Count()
};
foreach (var item in query)
{
WriteLine($"{item:A}");
}
WriteLine();
var extendQuery = Formulal.GetChampions()
.GroupBy(r => r.Country)
.OrderByDescending(g => g.Count())
.ThenBy(g => g.Key)
.Where(g => g.Count() >= 2)
.Select(g => new
{
Country = g.Key,
Count = g.Count()
});
foreach (var item in extendQuery)
{
WriteLine($"{item:A}");
}
}
public static void TestByLinqEight()
{
var query = (from r in Formulal.GetChampions()
orderby r.Country, r.LastName, r.FirstName
select r).Take(5);
foreach (var item in query)
{
WriteLine($"{item:A}");
}
WriteLine();
var extendQuery = Formulal.GetChampions()
.OrderBy(r => r.Country)
.ThenBy(r => r.LastName)
.ThenBy(r => r.FirstName)
.Take(5);
foreach (var item in extendQuery)
{
WriteLine($"{item:A}");
}
}
public static void TestByLinqSeven()
{
var query = from r in Formulal.GetChampions()
where r.Country == "Austria"
orderby r.Wins descending
select r;
foreach (var item in query)
{
WriteLine($"{item:A}");
}
WriteLine();
var extendQuery = Formulal.GetChampions().Where(r => r.Country == "Austria")
.OrderByDescending(r => r.Wins)
.Select(r => r);
foreach (var item in extendQuery)
{
WriteLine($"{item:A}");
}
}
public static void TestByLinqSix()
{
var query = from r in Formulal.GetChampions()
from c in r.Cars
where c == "Ferrari"
orderby r.LastName
select r.FirstName + " " + r.LastName;
foreach (var item in query)
{
WriteLine($"{item:A}");
}
WriteLine();
var extendQuery = Formulal.GetChampions().SelectMany(r => r.Cars, (r, c) => new { Racer = r, Car = c })
.Where(r => r.Car == "Ferrari")
.OrderBy(r => r.Racer.LastName)
.Select(r => r.Racer.FirstName + " " + r.Racer.LastName);
foreach (var item in extendQuery)
{
WriteLine($"{item:A}");
}
}
public static void TestByLinqFive()
{
object[] data = { "one", 2, 3, "four", "five", 6, new Racer("张三", "李四", "中国", 50, 10) };
var query = data.OfType<Racer>();
foreach (var item in query)
{
WriteLine($"{item:A}");
}
}
public static void TestByLinqFour()
{
var extendQuery = Formulal.GetChampions().
Where((r, index) => r.LastName.StartsWith("H") && index % 2 == 0);
foreach (var item in extendQuery)
{
WriteLine($"{item:A}");
}
}
public static void TestByLinqThree()
{
var query = from r in Formulal.GetChampions()
where r.Wins > 1 && (r.Country == "Italy" || r.Country == "Austria")
select r;
foreach (var item in query)
{
WriteLine($"{item:A}");
}
WriteLine();
var extendQuery = Formulal.GetChampions().Where(r => r.Wins > 1 && (r.Country == "Italy" || r.Country == "Austria"))
.Select(r => r);
foreach (var item in extendQuery)
{
WriteLine($"{item:A}");
}
}
public static void TestByLinqTwo()
{
var names = new List<string> { "Nino", "Alberto", "Juan", "Mike", "Phil" };
var namesWithJ = from n in names where n.StartsWith("J") orderby n select n;
WriteLine("First iteration");
foreach (var item in namesWithJ)
{
WriteLine(item);
}
WriteLine();
names.Add("John");
names.Add("Jim");
names.Add("Jack");
names.Add("Denny");
WriteLine("Second iteration");
foreach (var item in namesWithJ)
{
WriteLine(item);
}
}
public static void TestByLinqOne()
{
var query = from r in Formulal.GetChampions() where r.Country == "Italy" orderby r.Wins descending select r;
foreach (Racer item in query)
{
WriteLine($"{item:A}");
}
var extendQuery = Formulal.GetChampions().Where(r => r.Country == "Italy").OrderByDescending(r => r.Wins).Select(r => r);
WriteLine();
foreach (Racer item in extendQuery)
{
WriteLine($"{item:A}");
}
}
}
}