LINQ to Objects
前面我们在介绍LINQ的时候简单的提了一下LINQ to Objects,现在我们来学习一下LINQ to Objects,主要包括LINQ操作集合,字符串,文件目录。
先来看LINQ操作集合
LINQ可以操作.NET中的大多数集合,因为大多数集合都实现了IEnumerable<T>接口,并且可以很轻松的对集合的元素进行筛选,排序,分组等。
静态数组:
public class people
{
public string name;
public int age;
}
protected void Button1_Click(object sender, EventArgs e)
{
people[] person = new people[3];
for (int i = 0; i <person.Length; i++)
{
people peo = new people();
peo.name = "peo" + i.ToString();
peo.age = i;
person[i] = peo;
}
var result = from u in person where u.age!=0 orderby u.age descending select u;
foreach (var item in result)
{
Label1.Text += item.name;
}
}
动态数组:
protected void Button2_Click(object sender, EventArgs e)
{
ArrayList arraylist = new ArrayList();
for (int i = 0; i < 4; i++)
{
people peo = new people();
peo.name = "peo" + i.ToString();
peo.age = i;
arraylist.Add(peo);
} 操作ArrayList等非继承自泛型IEenumerable类型时要给指明范围变量u的类型,这在LINQ第一讲时已经提到过了
var result=from people u in arraylist where u.age!=0 orderby u.age descending select u;
foreach (var item in result)
{
Label2.Text += item.name;
}
}
泛型列表List<T>:
略
http://www.cnblogs.com/plin2008/archive/2009/05/05/1450201.html
http://www.cnblogs.com/wfnice12/archive/2009/04/17/1438390.html
泛型排序列表SortedList<TKey,TValue>:
泛型排序列表是由"键/值"对组成的集合,其内集合按照键的从小到大进行排序。每一个元素是KeyValuePair<Tkey,TValue>对象。键不能修改不能为空必须唯一,值可以为空。使用比较器来实现排序和比较操作。
protected void Button3_Click(object sender, EventArgs e)
{
SortedList<string, people> sortedlist = new SortedList<string, people>();
for (int i = 0; i < 4; i++)
{
people peo = new people();
peo.name = "peo" + i.ToString();
peo.age = i;
sortedlist.Add(i.ToString(), peo);
}
var result = from u in sortedlist where u.Value.age != 0 select u.Value;
u的类型是KeyValuePair<string, people>
foreach (var item in result)
{
Label3.Text+=item.name;
}
}
泛型双向链表LinkedList<T>:
泛型双向链表表示双向链表,它通过当前元素可以直接访问该元素的前一个元素(如果存在)和后一个元素(如果存在)。元素类型是LinkedListNode<T>。如果LinkedList<T>为空,则其First和Last属性的值也为空。
protected void Button4_Click(object sender, EventArgs e)
{
LinkedList<int> linkedlist = new LinkedList<int>();
linkedlist.AddFirst(0); 在开头处添加指定值的新元素
for (int i = 1; i < 5; i++)
{ Find()方法是找到第一个值是指定值的元素
AddAfter(0方法是在指定元素后面添加一个指定值的新元素
linkedlist.AddAfter(linkedlist.Find(i - 1), i);
}
var result = from u in linkedlist select u;
foreach (var item in result)
{
Label4.Text += item;
}
}
泛型队列Queue<T>:
泛型队列是一种先进先出的线性表。常用操作包括元素入队(Enqueue())元素出队(Dequeue())清空队列(Clear())等。可以包含重复元素和空元素。
protected void Button5_Click(object sender, EventArgs e)
{
Queue<int> queue = new Queue<int>();
for (int i = 0; i < 10; i++)
{
queue.Enqueue(i);
}
queue.Dequeue();
var result = from u in queue select u;
foreach (var item in result)
{
Label5.Text += item.ToString();
}
}
泛型堆栈Stack<T>:
泛型堆栈是一种限定在表尾进行插入删除的线性表。常见操作包括元素入栈(Push())元素出栈(Pop())清空堆栈(Clear())等。可以包含重复元素和空元素。
protected void Button6_Click(object sender, EventArgs e)
{
Stack<int> stack = new Stack<int>();
for (int i = 0; i < 10; i++)
{
stack.Push(i);
}
stack.Pop();
var result = from u in stack select u;
foreach (var item in result)
{
Label6.Text += item.ToString();
}
}
泛型哈希集HashSet<T>:
泛型哈希集基于集合的模型,可提供高性能的集合运算如并集,交集等。不能包含重复元素。不考虑排序。提供了并集,交集,补集等多个集合操作。
protected void Button7_Click(object sender, EventArgs e)
{
HashSet<int> hashset = new HashSet<int>();
for (int i = 0; i <10; i++)
{
hashset.Add(i);
}
var result = from u in hashset select u;
foreach (var item in result)
{
Label7.Text += item.ToString();
}
}
泛型字典Dictionary<TKey,TValue>:
泛型字典是由键/值对组成。元素类型为KeyValuePair<TKey,TValue>。键不能修改不能为空必须唯一,值可以为空。使用比较器来实现比较操作。
protected void Button8_Click(object sender, EventArgs e)
{
Dictionary<int, string> dictionary = new Dictionary<int, string>();
for (int i = 0; i < 5; i++)
{
dictionary.Add(i, i.ToString());
}
var result = from u in dictionary select u.Value;
foreach (var item in result)
{
Label8.Text += item;
}
}
泛型排序字典SortedDictionary<TKey,TValue>:
泛型排序字典泛型字典是由键/值对组成。其内集合按照键的从小到大进行排序。元素类型是KeyValuePair<Tkey,TValue>。键不能修改不能为空必须唯一,值可以为空。使用比较器来实现排序和比较操作。
protected void Button9_Click(object sender, EventArgs e)
{
SortedDictionary<int, string> sorteddictionary = new SortedDictionary<int, string>();
for (int i = 0; i < 5; i++)
{
sorteddictionary.Add(i, i.ToString());
}
var result = from u in sorteddictionary select u.Value;
foreach (var item in result)
{
Label9.Text += item;
}
}
泛型通用集合Collection<T>: using System.Collections.ObjectModel;
泛型通用集合与泛型列表List<T>非常相似,都是能够通过索引访问对象的强类型列表,索引从0开始。泛型通用集合还可以作为集合类型的基类使用,用户可以将自定义的集合类从泛型通用集合继承。
protected void Button10_Click(object sender, EventArgs e)
{
Collection<int> collection = new Collection<int>();
for (int i = 0; i < 5; i++)
{
collection.Add(i);
}
var result = from u in collection select u.ToString();
foreach (var item in result)
{
Label10.Text += item;
}
}
泛型绑定列表BindingList<T>: using System.ComponentModel;
泛型绑定列表能够提供支持数据绑定的泛型集合,它提供了IBindingList接口的具体泛型实现,可以用做创建双向数据绑定机制的基类,还可以通过AddNew()方法支持工厂创建的实例。
protected void Button11_Click(object sender, EventArgs e)
{
BindingList<int> bindinglist = new BindingList<int>();
for (int i = 0; i < 5; i++)
{
bindinglist.Add(i);
}
var result = from u in bindinglist select u.ToString();
foreach (var item in result)
{
Label11.Text += item;
}
}
再来看LINQ操作字符串
LINQ还可以操作字符串或字符串集合,如从字符串中查找指定的字符,从文本中查找指定的字符串,统计单词出现的次数(词频统计),另外使用LINQ还可以结合正则表达式来处理字符串。
查找指定字符:
protected void Button12_Click(object sender, EventArgs e)
{
string str = "sdhudhu;/&*(aj13483uhdui ppABC";
用到了字符类Char的多个静态方法来判断 是否数字 是否大写字母 是否标点符号
var result = from u in str where char.IsNumber(u)||char.IsUpper(u)||char.IsPunctuation(u) select u;
foreach (var item in result)
{
Label12.Text += item.ToString();
}
}
查找指定字符串:
先来学习一下字符串的split()方法
http://msdn.microsoft.com/zh-cn/library/ms228388(VS.80).aspx
第二个参数的解释
StringSplitOptions.None:返回值的数组含有空字符串元素
StringSplitOptions.RemoveEmptyEntries:返回值的数组不包括含有空字符串元素
查询含有字母o的字符串
protected void Button13_Click(object sender, EventArgs e)
{
string str = "Today,我去了我姥姥家.Her hair get white so 快;她的皱纹 so much,我真希望她能长命百岁.";
主要的操作就是通过观察用合理的分隔符把大字符串分成若干个小字符串
string[] str1=str.Split(new char[]{',','.',';',' '});
然后查询这些小字符串,利用字符串的Contains()方法来过滤这些小字符串
var result = from u in str1 where u.Contains("o") select u;
foreach (var item in result)
{
Label13.Text += item + "<br/>";
}
}
词频统计:
与查找指定字符串一样,都只适用于英文,因为英文之间一般都有空格,这样好分组,而汉语之间没有空格。
统计下列英文中每个单词出现的次数
protected void Button14_Click(object sender, EventArgs e)
{
string str="Followers of Islam inspect all believe in god's artificial limbs,
its full of love. Although there is no specific reference material
refers to the god so loved the world, but in the name of Allah
ninety-nine, have Alit's name Wadud, namely filled with love, in
the Koran destroy 0 chapter with 85:14 chapters mentioned. They think Allah is loving.";
按以下分隔符分组差不多每一组就是一个单词
string[] allstr = str.Split(new char[] {' ','.',','},StringSplitOptions.RemoveEmptyEntries);
去掉重复的单词,然后再返回这些单词组成的数组,关于这些查询操作可以看前面讲的
string[] disstr = allstr.Distinct<string>().ToArray<string>();
遍历每一个不重复的单词
foreach (var item in disstr)
{
在单词重复的数组里找这一个单词,并将结果返回给result
var result = from u in allstr where u.ToLower() == item.ToLower() select u;
得到该单词的数量
Label14.Text += item + "出现了" + result.Count().ToString() + "次" + "<br/>";
}
}
结合正则表达式来处理字符串: System.Text.RegularExpressions
查找字符串里以字母i开头的所有单词
protected void Button15_Click(object sender, EventArgs e)
{
string str = @"Followers of Islam inspect all believe in god's artificial limbs,
its full of love. Although there is no specific reference material
refers to the god so loved the world, but in the name of Allah
ninety-nine, have Alit's name Wadud, namely filled with love, in
the Koran destroy 0 chapter with 85:14 chapters mentioned. They think Allah is loving.";
Regex r = new Regex(@"^i"); 构造函数有一个参数是正则表达式字符串
string[] allstr = str.Split(new char[] { ' ', ',', '.' }, StringSplitOptions.RemoveEmptyEntries);
var result = from u in allstr where r.IsMatch(u) == true select u; 正则类的IsMatch判断是否符合匹配
foreach (var item in result)
{
Label15.Text += item + " ";
}
}
http://www.cnblogs.com/lucas/archive/2009/02/18/1392986.html
最后来看LINQ操作文件目录
现在我们来学习使用LINQ查询指定名称的文件,查询指定拓展名的文件,查询指定属性的文件,统计文件夹的大小等。
先来学习一下相关类
System.IO.File类和System.IO.FileInfo类及System.IO.Directory类和System.DirectoryInfo类
File,Directory是静态类(只有静态方法)而FileInfo,DirectoryInfo不是静态类
protected void Button16_Click(object sender, EventArgs e)
{ 得到某些特殊目录的路径 枚举.我的文档
string Folderpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
List<FileInfo> files = new List<FileInfo>();
Directory.GetFiles返回某目录下所有文件名(含路径)到string[]数组
foreach (var filename in Directory.GetFiles(Folderpath))
{ 将实例化的FileInfo(代表一个文件)添加到 List<FileInfo>
files.Add(new FileInfo(filename));
}
查找我的文档里中文件名有desktop的文件
var result = from u in files where u.Name.Contains("desktop")==true select u.FullName;
查询我的文档里后缀名是.exe的文件
var result = from u in files where u.Extension == ".exe" select u.Name;
查询我的文档里大于1KB小于5KB的文件
var result = from u in files where u.Length>1024&&u.Length<5120 select u.Name;
查询我的文档里所有文件总共的大小
var result = from u in files select u.Length;
long size = result.Sum();
Label16.Text =(size/1024/1024).ToString()+"MB";
foreach (var item in result)
{
Label16.Text += item;
}
}
比较两个文件夹里是否含有同名文件
protected void Button20_Click(object sender, EventArgs e)
{
string Folderpath1 = TextBox1.Text.Trim();
string Folderpath2 = TextBox2.Text.Trim();
List<FileInfo> files1 = new List<FileInfo>();
List<FileInfo> files2 = new List<FileInfo>();
foreach (var filename in Directory.GetFiles(Folderpath1))
{
files1.Add(new FileInfo(filename));
}
foreach (var filename in Directory.GetFiles(Folderpath2))
{
files2.Add(new FileInfo(filename));
}
var result = from u in files1 join v in files2 on u.Name equals v.Name select u.Name;
foreach (var item in result)
{
Label17.Text += item;
}
}
查询一个文件夹内所有内容中有"ILoveYou"的TXT文件
protected void Button21_Click(object sender, EventArgs e)
{
string Folderpath = TextBox1.Text.Trim();
List<FileInfo> files = new List<FileInfo>();
foreach (var filename in Directory.GetFiles(Folderpath))
{
files.Add(new FileInfo(filename));
}
var result = from u in files
where u.Extension == ".txt"
将指定文件按指定编码读出来
let content = File.ReadAllText(u.FullName, System.Text.Encoding.Default)
where content.Contains("ILoveYou")
select u.Name;
foreach (var item in result)
{
Label16.Text += item;
}
}