聚合运算

一、聚合
      聚合运算就是从一组值中计算出一个值。 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();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值