一、聚合
聚合运算就是从一组值中计算出一个值。 Aggregate扩展方法允许实现自定义的聚合运算。
聚合运算就是从一组值中计算出一个值。 Aggregate扩展方法允许实现自定义的聚合运算。
【示例】合并、求平均值、最大值、最小值
using System;
using System.Collections.Generic;
using System.Linq;
namespace 使用Aggregate扩展方法实现的自定义聚合
{
class Program
{
static void Main(string[] args)
{
//首先声明三个整数序列
int[] number1 = new int[] { 1, 2, 3 };
int[] number2 = new int[] { 4, 5, 6 };
int[] number3 = new int[] { 7, 8, 9 };
//将上述三个整数序列放到一个序列中
List<int[]> all = new List<int[]>
{
number1,number2,number3
};
//此时调用Aggregate扩展方法
Console.WriteLine("第一种写法:");
var allNumbers1 = all.Aggregate(
//第一个参数声明了累加器的类型,即这个方法调用所累加的是整数序列
//第二个参数是一个符合泛型委托Func的Lambda表达式。序列next会被一次添加到current后面,
//直到产生出最终的单个聚合运算
Enumerable.Empty<int>(), (current, next) =>
current.Union(next));
Array.ForEach(allNumbers1.ToArray(), n => Console.Write(n+" "));
Console.WriteLine();
Console.WriteLine("*****************平均值*****************");
Console.WriteLine(allNumbers1.Average());
Console.WriteLine("*****************最大值、最小值**************");
Console.WriteLine("max:{0}", allNumbers1.Max());
Console.WriteLine("min:{0}", allNumbers1.Min());
Console.WriteLine();
Console.WriteLine("第二种写法:");
//由于使用的是实例语法(all.aggregate),因此真正的第一个参数其实是对象all本身
var allNumbers2 = all.Aggregate((current, next) => current.Union(next).ToArray<int>());
Array.ForEach(allNumbers2.ToArray(), n => Console.Write(n + " "));
Console.WriteLine();
Console.WriteLine("第三种写法:");
//使用类语法,传入源序列,并提供累加器以及由一个Lambda表达式初始化的Func泛型委托
var allNumbers3 = Enumerable.Aggregate(all, Enumerable.Empty<int>(), (current, next) =>
current.Union(next));
Array.ForEach(allNumbers3.ToArray(), n => Console.Write(n + " "));
Console.ReadKey();
}
}
}
二、元素计数
扩展方法Count和LongCount可以用来实现元素计数功能。
【示例】
using System;
using System.Linq;
namespace 将Min函数用作一个Where谓词
{
class Program
{
static void Main(string[] args)
{
var games = new string[] { "hello1", "hisdisjdi", "xushuaihdsdinbnn", "hello2" };
//返回最短字符串的长度
Console.WriteLine("Shorted title: {0}", games.Min(t => t.Length));
//返回一个或多个最短的名称
var title = from game in games
where game.Length ==
games.Min(t => t.Length)
select game;
Array.ForEach(title.ToArray(), s => Console.Write(s + " "));
Console.ReadKey();
}
}
}
三、中位数
【示例】
using System;
using System.Collections.Generic;
using System.Linq;
namespace 中位数自定义聚合运算
{
class Program
{
static void Main(string[] args)
{
var numbers1 = new int[] { 1, 2, 3, 4,4, 5, 6, 7, 8, 9 };
var numbers2 = new int[] { 2, 3, 4, 5,4,6, 6, 7, 8, 9 ,10,11,9,5,3,4,3};
Console.Write(numbers1.Median1());//5
Console.WriteLine();
Console.Write(numbers2.Median2());//5
Console.ReadKey();
}
}
public static class MyAggregate
{
//公开枚举数,该枚举数支持在指定类型的集合上进行简单迭代。
public static T Median1<T>(this IEnumerable<T> source)
{
return source.ToArray()[source.Count() / 2];
}
public static T Median2<T>(this IEnumerable<T> source)
{
var ordered = from s in source orderby s select s;
return ordered.ToArray()[ordered.Count() / 2];
}
}
}
四、通过LINQ查询出文件夹中最大文件的3种办法
【示例】
using System;
using System.Linq;
using System.IO;
namespace 通过LINQ查询找出文件夹中的最大文件
{
class Program
{
static void Main(string[] args)
{
//SearchOption:指定是搜索当前目录,还是搜索当前目录及其所有子目录。
string[] files = Directory.GetFiles("D:\\myNotes\\LINQTest\\LINQTest", "*.*", SearchOption.AllDirectories);
Console.WriteLine("myNotes文件夹中的文件总数:{0}", files.Count());
//gets maximum
//FileInfo:初始化 System.IO.FileInfo 类的新实例,它作为文件路径的包装。
var max = (from fileName in files
let info = new FileInfo(fileName)
orderby info.Length descending
select
new { fileName = info.Name, Size = info.Length }).Take(1);
Console.WriteLine("Using Take: {0}", max.ElementAt(0));
//with anonymous type we have to indicate what to get the max of
var max1 = (from fileName in files
let info = new FileInfo(fileName)
select
new { fileName = info.Name, Size = info.Length }).Max(s => s.Size);
Console.WriteLine("Using Max with anonymous type: {0}", max1);
//使用辅助方法
var max11 = (from fileName in files
let info = new FileInfo(fileName)
select
new { fileName = info.Name, Size = info.Length, CompareTo = GetCompare(info.Length) });
Console.WriteLine("Using Max with anonymous type: {0}", max11.Max(s=>s.Size));
//with named type we lose convenience of anonymoous type but get
//inheritance,realization,for example we can implement IComparab
//and get the max of the whole object
var max2 = (from fileName in files
let info = new FileInfo(fileName)
select
new Temp { fileName = info.Name, Size = info.Length }).Max(s => s.Size);
Console.WriteLine("Using Max: {0}", max2);
Console.ReadKey();
}
//添加一个辅助方法
public static Func<T,int> GetCompare<T>(T y) where T : IComparable
{
return k => y.CompareTo(k);
}
}
//IComparable:定义由值类型或类实现的通用的比较方法,以为排序实例创建类型特定的比较方法
//这是一个接口,继承该接口需要实现其方法
public class Temp : IComparable<Temp>
{
public string fileName { get; set; }
public long Size { get; set; }
public int CompareTo(Temp o)
{
return Size.CompareTo(o.Size);
}
public override string ToString()
{
return string.Format("FileName: {0},Size: {1}", fileName, Size);
}
}
}
五、计算查询结果的总计
Sum是一个预定义的聚合运算,用于求取一个数值序列的总和。
【示例】
using System;
using System.Linq;
using System.IO;
namespace 按列求取总计
{
class Program
{
static void Main(string[] args)
{
string[] lines = File.ReadAllLines("D:\\myNotes\\text.txt");
//make sure we have some data
foreach (var s in lines)
{
Console.WriteLine("{0}",s);
}
var result = from line in lines
let values = line.Split(',')
let y = values
select (from str in y
select Convert.ToInt32(str));
Console.WriteLine();
for (int i = 0; i < result.Count(); i++)
{
Console.WriteLine("Total Column {0}: {1}", i + 1,
result.Sum(o => o.ElementAt(i)));
}
System.Threading.Thread.Sleep(5000);
Console.ReadKey();
}
}
}