记录LINQ标准查询运算符的学习

LINQ的延迟执行方式分两种,一种是流式处理,另一种是非流式处理。流式处理是指:当获取到的源元素足够计算时,就生成结果元素,不一定要获取全部源元素。

ToAsEnumerable

namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
Clump<string> fruitClump =
new Clump<string> { "apple", "passionfruit", "banana",
"mango", "orange", "blueberry", "grape", "strawberry" }; // 调用 Clump's Where() method with a predicate.
IEnumerable<string> query1 =
fruitClump.Where(fruit => fruit.Contains("o")); Console.WriteLine("query1 has been created.\n"); // 强迫使用 System.Linq.Enumerable 的 Where() 方法.
IEnumerable<string> query2 =
fruitClump.AsEnumerable().Where(fruit => fruit.Contains("o")); // Display the output.
Console.WriteLine("query2 has been created.");
}
}
class Clump<T> : List<T>
{
// Custom implementation of Where().
public IEnumerable<T> Where(Func<T, bool> predicate)
{
Console.WriteLine("In Clump's implementation of Where().");
return Enumerable.Where(this, predicate);
}
}
}

Cast

//ArrayList 继承的是IEnumerable 而非IEnumerable<T>
System.Collections.ArrayList fruits = new System.Collections.ArrayList();
fruits.Add("mango");
fruits.Add("apple");
fruits.Add("lemon"); //OrderBy扩展的是IEnumerable<T>。因此通过Cast<T>转为IEnumerable<T>
IEnumerable<string> query =
fruits.Cast<string>().OrderBy(fruit => fruit).Select(fruit => fruit); foreach (string fruit in query)
{
Console.WriteLine(fruit);
}

Concat 连接序列

Pet[] cats = GetCats();
Pet[] dogs = GetDogs(); IEnumerable<string> query =
cats.Select(cat => cat.Name).Concat(dogs.Select(dog => dog.Name)); foreach (string name in query)
{
Console.WriteLine(name);
} //用另一个select重载试试
IEnumerable<string> query1 =
    cats.Select((pet, index) => { if (index == 2) { return pet.Name; } else { return ""; } })
    .Concat(dogs.Select(dog=>dog.Name))

DefaultIfEmpty 如果序列为空,则返回一个具有默认值的单例类集合

Pet defaultPet = new Pet { Name = "Default Pet", Age =  };

List<Pet> pets1 =
new List<Pet>{ new Pet { Name="Barley", Age= },
new Pet { Name="Boots", Age= },
new Pet { Name="Whiskers", Age= } }; foreach (Pet pet in pets1.DefaultIfEmpty(defaultPet))
{
Console.WriteLine("Name: {0}", pet.Name);
} List<Pet> pets2 = new List<Pet>(); foreach (Pet pet in pets2.DefaultIfEmpty(defaultPet))
{
Console.WriteLine("\nName: {0}", pet.Name);
}

Distinct 返回元素不重复的元素,可以使用默认比较器,也可以传个新的

Product product1 = new Product { Name = "apple", Code =  };
Product[] products = { product1,
new Product { Name = "orange", Code = },
product1,
new Product { Name = "lemon", Code = } }; //在此处,使用默认比较器
IEnumerable<Product> noduplicates = products.Distinct(); //该不该生产当前结果元素,只需要判断之前的源元素有没有一样的,知道判断到有,就不生成
foreach (var product in noduplicates)
Console.WriteLine(product.Name + " " + product.Code);

Except 返回序列之间的差值

double[] numbers1 = { 2.0, 2.0, 2.1, 2.2, 2.3, 2.3, 2.4, 2.5 };
double[] numbers2 = { 2.2 }; IEnumerable<double> onlyInFirstSet = numbers1.Except(numbers2); foreach (double number in onlyInFirstSet)
Console.WriteLine(number);

GroupJoin 两个序列进行分组联接

Person magnus = new Person { Name = "Hedlund, Magnus" };
Person terry = new Person { Name = "Adams, Terry" }; Pet barley = new Pet { Name = "Barley", Owner = terry };
Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus }; List<Person> people = new List<Person> { magnus, terry };
List<Pet> pets = new List<Pet> { barley, boots, daisy }; //Pet的Owner和Person关联
var query =
people.GroupJoin(pets,
person => person,
pet => pet.Owner,
(person, petCollection) =>
new
{
OwnerName = person.Name,
Pets = petCollection.Select(pet => pet.Name)
}); foreach (var obj in query)
{
Console.WriteLine("{0}:", obj.OwnerName);
foreach (string pet in obj.Pets)
{
Console.WriteLine(" {0}", pet);
}
}

Intersect 求序列交集

Product product = new Product { Name = "apple", Code =  };

Product[] store1 = { product,
new Product { Name = "orange", Code = } }; Product[] store2 = { product,
new Product { Name = "lemon", Code = } }; //在这里 使用默认比较器求差值
var products = store1.Intersect(store2); foreach(var item in products)
{
Console.WriteLine(item.Name);
}

Join基于匹配建对序列的元素进行关联

Person magnus = new Person { Name = "Hedlund, Magnus" };
Person terry = new Person { Name = "Adams, Terry" };
Person charlotte = new Person { Name = "Weiss, Charlotte" }; Pet barley = new Pet { Name = "Barley", Owner = terry };
Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus }; List<Person> people = new List<Person> { magnus, terry, charlotte };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, daisy }; //pet的owner和person关联
var query =
people.Join(pets,
person => person,
pet => pet.Owner,
(person, pet) =>
new { OwnerName = person.Name, Pet = pet.Name }); foreach (var obj in query)
{
Console.WriteLine(
"{0} - {1}",
obj.OwnerName,
obj.Pet);
}

OfType 根据指定类型筛选序列指定的元素

System.Collections.ArrayList fruits = new System.Collections.ArrayList();
fruits.Add("Mango");
fruits.Add("Orange");
fruits.Add("Apple");
fruits.Add(3.0);
fruits.Add("Banana"); // Apply OfType() to the ArrayList.
IEnumerable<string> query1 = fruits.OfType<string>(); Console.WriteLine("Elements of type 'string' are:");
foreach (string fruit in query1)
{
Console.WriteLine(fruit);
} Console.WriteLine("Elements of type 'int' are:");
IEnumerable<double> query2 = fruits.OfType<double>();
foreach (var num in query2)
{
Console.WriteLine(num);
}

Range 生成指定范围内的序列

IEnumerable<int> squares = Enumerable.Range(, ).Select(x => x * x);

foreach (int num in squares)
{
Console.WriteLine(num);
}

Repeat生成一个包含重复值的序列

IEnumerable<string> strings =
Enumerable.Repeat("I like programming.", ); foreach (String str in strings)
{
Console.WriteLine(str);
}

Select 将序列中的每个元素投影到新表单

string[] fruits = { "apple", "banana", "mango", "orange",
"passionfruit", "grape" }; var query =
fruits.Select((fruit, index) => new { index,str=fruit.Substring(,index)}); foreach (var obj in query)
{
Console.WriteLine("{0}", obj);
}

SelectMany 将序列的每个元素投影到 IEnumerable<T> ,然后,每个元素投影到的结果序列合并成一个大的序列。

PetOwner[] petOwners =
{
new PetOwner { Name="Higa",
Pets = new List<string>{ "Scruffy", "Sam" } },
new PetOwner { Name="Ashkenazi",
Pets = new List<string>{ "Walker", "Sugar" } },
new PetOwner { Name="Price",
Pets = new List<string>{ "Scratches", "Diesel" } },
new PetOwner { Name="Hines",
Pets = new List<string>{ "Dusty" } }
}; //想要的结果,Higa养猪人都有哪些猪,排成一行行的结果。
// {Owner=Higa, Pet=Scruffy}
// {Owner=Higa, Pet=Sam} var query = petOwners.Where(owner=>owner.Name=="Higa")
.SelectMany(owner => owner.Pets, (owner, pet) => new { owner = owner.Name, pet });
foreach(var obj in query)
{
Console.WriteLine(obj);
}
Skip 跳过指定数量的元素,返回一个剩下元素组成的新序列
int[] grades = { , , , , , ,  };

IEnumerable<int> lowerGrades =
grades.Skip(); foreach (int grade in lowerGrades)
{
Console.WriteLine(grade);
} //返回结果
//70
//56
//92
//98
//
SkipWhile 当条件为true,前面的元素忽略,剩下的元素组成一个新序列。
下面有坑,请注意。
int[] grades = { , , , , , ,  };

IEnumerable<int> newGrades =
grades.SkipWhile(grade => grade >= ); foreach (int grade in newGrades)
{
Console.WriteLine(grade);
} Console.WriteLine("\n"); //排序之后的跳过
IEnumerable<int> lowerGrades =
grades.OrderByDescending(g=>g).SkipWhile(grade => grade >= ); foreach (int grade in lowerGrades)
{
Console.WriteLine(grade);
} 控制台输出结果:
59
82
70
56
92
98
85 70
59
5
Take从序列的开头返回指定数量的相邻元素
int[] grades = { , , , , , ,  };

IEnumerable<int> newGrades =
grades.Take(); foreach (int grade in newGrades)
{
Console.WriteLine(grade);
}
TakeWhile 只要指定的条件为 true,就会返回序列的元素,从开头开始取,直到不满足条件,剩下的元素也不返回了。
string[] fruits = { "apple", "banana", "mango", "orange",
"passionfruit", "grape" }; IEnumerable<string> query =
fruits.TakeWhile(fruit => String.Compare("orange", fruit, true)!= ); foreach (string fruit in query)
{
Console.WriteLine(fruit);
} Console.WriteLine("\n"); IEnumerable<string> query1 =
fruits.TakeWhile(fruit => String.Compare("apple", fruit, true) == ); foreach (string fruit in query1)
{
Console.WriteLine(fruit);
} /*
输出结果: apple
banana
mango apple
*/

Union 生成两个序列的并集

跑了好些示例,发现只要通过标准运算符生成的元素如果要通过判断相等操作,都有比较器可以传入的函数。

int[] ints1 = { , , , , , , ,  };
int[] ints2 = { , , , , , , , }; IEnumerable<int> union = ints1.Union(ints2); foreach (int num in union)
{
Console.Write("{0} ", num);
}

Where 基于条件筛选序列,太常用了。

List<string> fruits =
new List<string> { "apple", "passionfruit", "banana", "mango",
"orange", "blueberry", "grape", "strawberry" }; IEnumerable<string> query = fruits.Where(fruit => fruit.Length < ); foreach (string fruit in query)
{
Console.WriteLine(fruit);
}
/*
This code produces the following output: apple
mango
grape
*/
 

LINQ标准查询运算符的执行方式-延时之流式处理的更多相关文章

  1. LINQ标准查询运算符的执行方式-即时

    即时,声明查询的位置立即执行.查询返回如果是不可以枚举的的结果,都会立即执行. 执行方式为“”即时”的查询运算符有下面这些. Aggregate 应用累计器函数和结果选择器,返回传入泛型类型TSour ...

  2. C#3.0新增功能09 LINQ 标准查询运算符 03 按执行方式的分类

    连载目录    [已更新最新开发文章,点击查看详细] 标准查询运算符方法的 LINQ to Objects 实现主要通过两种方法之一执行:立即执行和延迟执行.使用延迟执行的查询运算符可以进一步分为两种 ...

  3. .NET LINQ标准查询运算符

    标准查询运算符概述      “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法. 大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了 IEnumerable<T> ...

  4. C#3.0新增功能09 LINQ 标准查询运算符 04 运算

    连载目录    [已更新最新开发文章,点击查看详细] 本篇主要介绍标准查询运算符的常用运算功能. 01 对数据排序 排序操作基于一个或多个属性对序列的元素进行排序. 第一个排序条件对元素执行主要排序. ...

  5. C#3.0新增功能09 LINQ 标准查询运算符 01 概述

    连载目录    [已更新最新开发文章,点击查看详细] 标准查询运算符 是组成 LINQ 模式的方法. 这些方法中的大多数都作用于序列:其中序列指其类型实现 IEnumerable<T> 接 ...

  6. C#3.0新增功能09 LINQ 标准查询运算符 02 查询表达式语法

    连载目录    [已更新最新开发文章,点击查看详细] 某些使用更频繁的标准查询运算符具有专用的 C# 语言关键字语法,使用这些语法可以在查询表达式中调用这些运算符. 查询表达式是比基于方法的等效项更具 ...

  7. linq标准查询运算符

    Order By操作 适用场景:对查询出的语句进行排序,比如按时间排序等等. 说明:按指定表达式对集合排序:延迟,:按指定表达式对集合排序:延迟,默认是升序,加上descending表示降序,对应的扩 ...

  8. .NET中那些所谓的新语法之四:标准查询运算符与LINQ

    开篇:在上一篇中,我们了解了预定义委托与Lambda表达式等所谓的新语法,这一篇我们继续征程,看看标准查询运算符和LINQ.标准查询运算符是定义在System.Linq.Enumerable类中的50 ...

  9. “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法

    “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> 接口或 IQueryable& ...

随机推荐

  1. C0nw4y's L!f3 G4me 代码实现

    这是我转载的博客,关于这个游戏的介绍.估计没人能get到这个游戏的blingbling的地方吧.还是蛮惊叹的. 因为这里网络实在惨淡,闲来无事实现了下这个游戏,UI尽量美化了,可惜python配置不知 ...

  2. 学习 lind api 十月 第5弹

    继续 四弹里的 自定义的api response message 但是 那上面的 那些值得也是包含

  3. 源码的说明 ASP.NET MVC 5框架揭秘.zip

    第1章 S101 MVP(SC)模式中Presenter与View之间的交互 S102 迷你版的ASP.NET MVC框架 第2章 S201 通过路由实现请求地址与.aspx页面的映射 S202 基本 ...

  4. [ Python入门教程 ] Python中JSON模块基本使用方法

    JSON (JavaScript Object Notation)是一种使用广泛的轻量数据格式,Python标准库中的json模块提供了一种简单的方法来编码和解码JSON格式的数据.用于完成字符串和p ...

  5. Java多态之Father f=new Son();

    成员变量静态方法看左边,非静态方法编译看左边,运行看右边. 左边Father f其实是定义了一个Father类的对象,而右边new Son()可以只理解为是一个重写了Father类方法的对象. 因此, ...

  6. SpringBoot检索篇Ⅳ --- 整合ElasticSearch

    知识储备:  关于ElasticSearch的基本使用我已经在上一篇文章介绍过了(传送门),本篇文章主要讲述的是SpringBoot与ElasticSearch的整合使用. SpringBoot与El ...

  7. 九 Shell中的数组

    数组:用一个变量存储一组数据,并能够对这组数据中的某一个数据单独操作. 数组的类型:一维数组.二维数组.多维数组 变量的类型 Shell中默认无类型 变量的值默认均视为文本 用在数字运算中时,自动将其 ...

  8. PAT_B_PRAC_1003养兔子

    题目描述 一只成熟的兔子每天能产下一胎兔子.每只小兔子的成熟期是一天. 某人领养了一只小兔子,请问第N天以后,他将会得到多少只兔子. 输入描述: 测试数据包括多组,每组一行,为整数n(1≤n≤90). ...

  9. python 内置模块之os、sys、shutil

    一.OS模块 用于提供系统级别的操作. OS 目录和文件 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改 ...

  10. [python]getpass模块

    python3的input函数不能隐藏用户输入,可以用getpass模块的getpass方法获取用户输入的时候用于隐藏显示密码. *需要注意的是该方法在IDE中看不到隐藏效果,在内置IDLE中会有Ge ...