• c# List 里面的Linq方法


    虽然List里的linq方法(其实是Enumarable的)大部分比较简单 ,但是如果能够灵活运用也是提高code质量,可读性和coding能力的有效途径。而且其中有些方法,例如 Join, 光看注释可能会有点懵。 最近把他们go through了一遍。代码如下。

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Linq;
    using System.Collections.ObjectModel;
    using System.Collections;

    namespace ListMethodTest
    {

    public class TestItem
    {
    public int number { get; set; }
    public string str { get; set; }

    //used for SelectMany
    public List<string> children { get; set; }

    public override int GetHashCode()
    {
    return number;
    }
    }

    public class InnerClass
    {
    public int id { get; set; }
    public string name { get; set; }
    }

    public class ChildTestItem : TestItem
    { }

    public class ConvertTest
    {
    public int a { get; set; }
    }

    public partial class _Default : System.Web.UI.Page
    {
    List<TestItem> lst1 = new List<TestItem>();
    protected void Page_Load(object sender, EventArgs e)
    {

    lst1.Add(new TestItem() { number = 3, str = "dsdfsf", children = new List<string>() { "c1", "c2" } });
    lst1.Add(new TestItem() { number = 1, str = "csdfsdf", children = new List<string>() { "c3", "c4" } });
    lst1.Add(new TestItem() { number = 2, str = "aasdfsdf" });
    lst1.Add(new TestItem() { number = 2, str = "222" });


    int part = 3;
    switch (part)
    {
    case 1: Part1();break;
    case 2: Part2(); break;
    case 3: Part3(); break;
    default: break;
    }
    }

    private void Part3()
    {
    int sum = lst1.Sum(x => x.number);
    List<TestItem> take = lst1.Take(3).ToList();

    //同样 take前面的
    List<TestItem> takewhile = lst1.TakeWhile(x => x.number == 3).ToList();

    //key必须唯一
    // Dictionary<int,TestItem> toDic= lst1.ToDictionary(x => x.number);

    //Ilookup:IEnumerable<TElement> this[TKey key] { get; } 所以可以有重key
    ILookup<int, TestItem> lookup = lst1.ToLookup(x => x.number);

    //lst1.TrimExcess();

    bool trueforall = lst1.TrueForAll(x => x.number > -1);

    List<TestItem> where = lst1.Where(x => x.number == 2).ToList();

    }

    void Part2()
    {
    // 里面的 item和原来的是一个引用,即便 不重写GetHashCode
    List<TestItem> getR = lst1.GetRange(1, 2);



    IEnumerable<IGrouping<int, TestItem>> gb = lst1.GroupBy(x => x.number);

    int io = lst1.IndexOf(lst1[1]);

    lst1.Insert(0, new TestItem() { number = 0, str = "00" });


    List<TestItem> toInsert = new List<TestItem>()
    {
    new TestItem() { number = 0, str = "InsertRange0"},
    new TestItem() { number = 2, str = "InsertRange1" },
    new TestItem() { number = 9, str = "InsertRange2" },
    };
    //lst1.InsertRange(0, toInsert);

    //返回 lst1中与 toInsert 相等的 元素
    List<TestItem> Intersect = lst1.Intersect(toInsert, new DistinctTest()).ToList();


    List<InnerClass> inner = new List<InnerClass>() {

    new InnerClass(){ id=1, name="name1"},
    new InnerClass(){ id=2, name="name2"},
    new InnerClass(){ id=3, name="name3"},

    };

    // 2个list的 TKEY 类型必须一致, 返回 key相等的组合 ,其实就是 key相等的 inner join
    // 最后一个委托只是根据组合 生成 返回的结果
    IEnumerable join = lst1.Join(inner, x => x.number, i => i.id, (a, b) => new { a.number, a.str, b.id, b.name });

    // 类似 dictionary, lst1为key, 匹配的 InnerClass 的集合为value ,即使集合count为0(没有匹配) ,也会组合
    IEnumerable gj = lst1.GroupJoin(inner, x => x.number, i => i.id, (a, b) => new { id = a.number, name = a.str, lst = b });


    IEnumerable zip = lst1.Zip(inner, (x, y) => new { x.number, x.str, y.id, y.name });

    TestItem last = lst1.Last(x => x.number == 2);

    int lindex = lst1.LastIndexOf(lst1[2]);

    int max = lst1.Max(x => x.number);
    int min = lst1.Min(x => x.number);

    //lst1.Add(new ChildTestItem());
    //IEnumerable<ChildTestItem> ot= lst1.OfType<ChildTestItem>();


    List<TestItem> ob = lst1.OrderBy(x => x.str).ToList();

    //lst1.Sort((a, b) => {
    // if( a.number< b.number) return -1;
    // else if( a.number == b.number) return 0;
    // else return 1;
    // } );

    // TestItem temp =lst1[0];
    // bool remove = lst1.Remove(temp);

    // int ra= lst1.RemoveAll(x => x.number == 2);

    // lst1.RemoveAt(2);

    //lst1.RemoveRange(2, 2);

    //lst1.Reverse();

    // select 是变形用的 ,这个词太唬人了,别被他的外表所蒙蔽
    IEnumerable select = lst1.Select(x => new { id = x.number, name = x.str, g = Guid.NewGuid() });
    IEnumerable select1 = lst1.Select((x, y) => new { id = x.number, name = x.str, index = y, g = Guid.NewGuid() });
    //flatten
    IEnumerable SelectMany = lst1.SelectMany(x => x.children == null ? new List<string>() : x.children);

    List<TestItem> s1 = new List<TestItem>()
    {
    new TestItem(){ number=1 ,str="sdf" }
    };


    List<TestItem> s2 = new List<TestItem>()
    {
    new TestItem(){ number=1 }
    };

    //个数不一样肯定 false
    bool se = s1.SequenceEqual(s2, new DistinctTest());

    List<TestItem> union = s1.Union(s2).ToList();


    //不single的话 throw exception
    //TestItem singe = lst1.Single(x => x.number ==2);


    List<TestItem> skip = lst1.Skip(2).ToList();
    //注意 bypass 前面的element
    List<TestItem> SkipWhile = lst1.SkipWhile(x => x.number == 0).ToList();

    }

    void Part1()
    {
    // ( (item 1,2 的结果 ) 和item 3的结果)和item 4的结果
    TestItem agg = lst1.Aggregate((i, j) => { i.number += j.number; return i; });

    bool all = lst1.All(i => i.str.Contains("c"));

    bool any = lst1.Any(i => i.str.Contains("c"));


    ParallelQuery p = lst1.AsParallel();


    IQueryable<TestItem> q = lst1.AsQueryable();

    var query = from ti in q where ti.number == 2 select ti;

    ReadOnlyCollection<TestItem> readonlylst = lst1.AsReadOnly();


    double average = lst1.Average(i => i.number);

    int index = lst1.BinarySearch(new TestItem() { number = 1, str = "123123" }, new CompareClass());

    //如果lst1是非泛型的集合 ,转换之后就可以用泛型的方法啦! where, any ,select , all等
    IEnumerable<TestItem> castedLst = lst1.Cast<TestItem>();

    List<TestItem> lsttoConcat = new List<TestItem>() { new TestItem() { number = 4 } };
    List<TestItem> concatedLst = lst1.Concat(lsttoConcat).ToList();


    TestItem t = new TestItem() { number = 4 };
    lst1.Add(t);
    //bool contains = lst1.Contains<TestItem>(t);
    bool contains = lst1.Contains<TestItem>(new TestItem() { number = 4 });
    //bool contains = lst1.Contains<string>("sdfsdf"); it's wrong!

    List<ConvertTest> convertedLst = lst1.ConvertAll(i => new ConvertTest() { a = i.number });

    TestItem[] arr = new TestItem[10];
    lst1.CopyTo(arr, 3);


    //下面defLst count 为 0
    IEnumerable<TestItem> defLst = lst1.DefaultIfEmpty();

    IEnumerable<TestItem> dsicLst = lst1.Distinct();

    lst1.Add(new TestItem() { number = 4, str = "sdfsd" });
    IEnumerable<TestItem> dsicLst1 = lst1.Distinct<TestItem>(new DistinctTest());


    TestItem elementat = lst1.ElementAt(1);
    TestItem elementatORDefault = lst1.ElementAtOrDefault(10);


    List<TestItem> toexcept = new List<TestItem>()
    {
    lst1[2],
    lst1[3]

    };

    IEnumerable<TestItem> exceptedLst = lst1.Except(toexcept);



    bool exist = lst1.Exists(i => i.number == 4);


    TestItem find = lst1.Find(i => i.number == 4);

    List<TestItem> findall = lst1.FindAll(i => i.number == 4);

    int fIndex = lst1.FindIndex(i => i.number == 4);


    TestItem fLast = lst1.FindLast(i => i.number == 4);


    int lastIndex = lst1.FindLastIndex(i => i.number == 4);

    TestItem first = lst1.First(x => x.number == 4);

    lst1.ForEach(x => x.str = x.number == 4 ? "4" : x.str);
    }


    }

    public class DistinctTest : IEqualityComparer<TestItem>
    {
    public bool Equals(TestItem x, TestItem y)
    {
    if (x.number == y.number) return true;
    else return false;
    }


    public int GetHashCode(TestItem obj)
    {
    //HashCode默认情况就是地址的散列码,跟散列算法有关系,所以默认情况不同对象的hashcode是不一样的,所以要重写TestItem的GetHashCode方法。
    //用最简单的方法来说,hashcode就是一个签名。当两个对象的hashcode一样时,两个对象就"有可能"一样。如果不一样的话两个对象就"肯定"不一样。
    return obj.GetHashCode();
    }
    }

    public class CompareClass : IComparer<TestItem>
    {
    public int Compare(TestItem x, TestItem y)
    {
    if (x.number < y.number) return -1;
    else if (x.number == y.number) return 0;
    else return 1;
    }
    }
    }

    转载自:http://www.cnblogs.com/wangtian52127/archive/2012/03/30/2425482.html
  • 相关阅读:
    vue 鼠标移入移出事件执行多次(尤其ie)
    jquery input file 多图上传,单张删除,查看
    pc端vue 滚动到底部翻页
    element-ui默认样式修改
    element-ui上传一张图片后隐藏上传按钮
    echarts字体适配
    SQLServer之查询当前服务器下所有目录视图表
    SQLServer之服务器连接
    React学习之路之创建项目
    SQLServer之列数据转换为行数据
  • 原文地址:https://www.cnblogs.com/zcm123/p/2567287.html
Copyright © 2020-2023  润新知