首先申明一下,写此博文的目的是纪录一下,知识都是现成的,只是整理一下,为了让自己更容易看懂,比在其他地方更容易明白。因为它们太常用了,不忍心每次都去用那么长的时间查看MSDN,希望能在这里用理少的时间来理解并运用其用法。最终目标是减少从接触到能理解并使用的时间。

List<T>类型的查找操作Find与FindIndex

             Point pt;
List<Point> lstPs = new List<Point>();
for (int i = ; i < ; i++)
{
pt = new Point(i, i + );
lstPs.Add(pt);
}
Point pp = lstPs.Find( delegate(Point p)//pp是结果Point,是查到的目标
{
return p.X == ;//这个是有目标的情况,如果没有这个X==9的这个点呢?
});
Point ppNo = lstPs.Find(delegate(Point p)
{
return p.X == ;//如果队列中没有目标点,返回的是Point类型的默认值
});
Console.WriteLine("目标点是:"+pp);
Console.WriteLine("没有发现目标点时得到的是默认值:" + ppNo);
/*
返回结果如下:
目标点是:{X=9,Y=109}
没有发现目标点时得到的是默认值:{X=0,Y=0}
*/

List过滤

  结论:使用Find方法时要注意return 语句后面是bool类型的表达式,不是想当然的返回一个目标T类型,这里是Point类型。在List中有目标就查到目标,如果没有话就返回 T类型的默认值(default(T)可得到)。

  FindIndex:

    //名字 值 单位组合  nvu
struct NameValueUnit
{
public string oname;
public string ovalue;
public string ounit;
}
//移除一个组合
public void RemoveByName(string name)
{
int index = -;
index = lstNVU.FindIndex(delegate(NameValueUnit nvu)
{
if (nvu.oname.Equals(name))
{
return true;
}
else
{
return false;
}
});
lstNVU.RemoveAt(index);
}

FindIndex的使用

下面来看看FindAll的源码:

        public List<T> FindAll(Predicate<T> match) {
if( match == null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock(); List<T> list = new List<T>();
for(int i = ; i < _size; i++) {
if(match(_items[i])) {
list.Add(_items[i]);
}
}
return list;
}

FindAll

主要依赖Predicate委托,那看一下这个委托:

public delegate bool Predicate<in T>(T obj); 

传入一个用于判断满足条件的委托实例,就可以得到目标数据。很巧妙!

List查询最近值

//List获取最近值原理。
//从List中寻找离number最近的数
list.Aggregate((x,y) => Math.Abs(x-number) < Math.Abs(y-number) ? x : y);
//从源码上看是遍历所有元素,时间复杂度是O(n);

最近值

DataTable的使用

  1、添加列

  2、添加行

  3、查找数据select方法的使用

  4、获取列名

            DataTable dtAll = new DataTable();

            //下面建立列过程:分别添加名为ID的列,名为name的列,名为score的列,类型分别是long,string,float。
DataColumn dc = new DataColumn("ID", typeof(long));
dtAll.Columns.Add(dc);
dc = new DataColumn("name", typeof(string));
dtAll.Columns.Add(dc);
dc = new DataColumn("score", typeof(float));
dtAll.Columns.Add(dc);
//为表添加行
DataRow dr = dtAll.NewRow();
dr[] = ;//其实是一个装箱过程,把int装箱为object
dr[] = "john";
dr[] = 98.5;
dtAll.Rows.Add(dr); dr = dtAll.NewRow();
dr[] = ;
dr[] = "Lucy";
dr[] = 23.5;
dtAll.Rows.Add(dr);
DataRow[] drs = dtAll.Select("ID=2009000");
Console.WriteLine(drs[][]);//查找到的第一个人的分数score,结果是当然的98.5

添加行和列

  几个需要注意的地方。第一、先添加列,而不是先添加行,在添加列后再补充每行;第二、向第n行的第m列添加数据时是一个装箱过程,取出目标数据时需要拆箱操作,一般是Convert.To***方法;第三、查寻时的过滤条件是string,语法是SQL相仿。

  一个例子:查找条件不同时的结果。

             DataTable dt = new DataTable();
for (int i = ; i < ; i++)//加两列
{
DataColumn dc = new DataColumn();
if (i == )
{
dc.ColumnName = "we";
dc.DataType = typeof(int);
}
dt.Columns.Add(dc);
} DataRow dr = dt.NewRow();
dr[] = ;
dr[] = "ddd";
dt.Rows.Add(dr); dr = dt.NewRow();
dr[] = ;
dr[] = "";
dt.Rows.Add(dr); string condition = "we>70 and we<" + ;
DataRow[] drs = dt.Select(condition);
string tmp = drs[][].ToString();//能输出正常结果,根据条件condition的不同输出不同的结果
Console.WriteLine(tmp);

Select条件查找的使用

  condition作为条件,使用SQL语法 .

  要获取列名只用一条语句 :

    dataTable.Columns[i].ColumnName;//得到第i列的列名

5、复制表结构

DataTable dt2 = dt1.Clone();//这样把表dt1的结构复制到表dt2中,但是不复制数据

6、得到DataTable的第begin行到第end行的数据,并返回一个过滤后的DataTable

/// <summary>
/// 过滤第begin行到到end行之间的数据行
/// </summary>
/// <param name="begin">开始行</param>
/// <param name="end">结束行</param>
/// <param name="oDT">源表</param>
/// <returns></returns>
public static DataTable DtSelectRows(int begin,int end, DataTable oDT)
{ if (oDT.Rows.Count < end) return oDT;
DataTable NewTable = oDT.Clone();
DataRow[] rows = oDT.Select("1=1");
for (int i = begin; i <=end; i++)
{
NewTable.ImportRow((DataRow)rows[i]);
}
return NewTable;
}

过滤第begin行到到end行之间的数据行

交换两行

        public static DataTable SwapRow(int index1, int index2, DataTable dt)
{
DataRow dr = dt.NewRow();
dr.ItemArray = dt.Rows[index1].ItemArray;
dt.Rows[index1].ItemArray = dt.Rows[index2].ItemArray;
dt.Rows[index2].ItemArray = dr.ItemArray;
return dt;
}

交换两行

DataView的一些用法

  1、使用DataTable得到DataView时一个问题

  原始有问题的代码如下:

             DataView dvClass = booksClass.dtClass.DefaultView;
DataView dvChild = booksClass.dtClass.DefaultView;
dvClass.RowFilter="father='11'";
dvChild.RowFilter = "father='22'";

  这样做后,回头再看发现dvClass 和 dvChild的RowFilter是相同的,都是"father='22'";原来是因为dvClass dvChild引用了同一个实例。所以修改如下:

             DataView dvChild = new DataView(booksClass.dtClass);// booksClass.dtClass.DefaultView;
dvClass.RowFilter = "father='11'";
dvChild.RowFilter = "father='222'";

  问题得以解决,两个DataView就变得独立了。

List的排序

  private void InitSS()
{
List<MyStruct> lstStructs = new List<MyStruct>(); MyStruct ms1, ms2, ms3, ms4;
ms1.age = ;
ms1.name = "aa";
lstStructs.Add(ms1); ms2.age = ;
ms2.name = "bb";
lstStructs.Add(ms2); ms3.age = ;
ms3.name = "dd";
lstStructs.Add(ms3); ms4.age = ;
ms4.name = "ss";
lstStructs.Add(ms4); textBox1.Text = string.Empty; textBox1.Text += "排序前:\r\n";
foreach (var item in lstStructs)
{
//Console.WriteLine(item.Id + "," + item.Name);
textBox1.Text += item.age + ":" + item.name + "\r\n";
} lstStructs.Sort(delegate(MyStruct info1, MyStruct info2)
{
return info1.age.CompareTo(info2.age);//排序的关键
});
//Console.WriteLine("*****ListSort**********");
textBox1.Text += "排序后:\r\n";
foreach (var item in lstStructs)
{
//Console.WriteLine(item.Id + "," + item.Name);
textBox1.Text += item.age + ":" + item.name + "\r\n";
}
} private void btnSsort_Click(object sender, EventArgs e)
{
InitSS();
}
} struct MyStruct
{
public int age;
public string name;
}

排序示例

5、复制表结构

Dictionary

1、根据value得到key

 var firstKey = dic.FirstOrDefault(q => q.Value == "").Key;  //get first key  其中q为一个键值对

两个List<>互相过滤数据

代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace AboutList
{
class Program
{
static void Main(string[] args)
{
Student s1 = new Student { Age=,Name="deng"};
Student s2 = new Student { Age = , Name = "li" };
Student s3 = new Student { Age = , Name = "张" };
Student s4 = new Student { Age = , Name = "王" };
Student s5 = new Student { Age = , Name = "李" };
List<Student> list1 = new List<Student> { s1, s2, s3, s4, s5 };
List<Student> list2 = new List<Student> { s1,s2};
//下面查找不在list2中,只在list1中的Student实例
List<Student> listRes = list1.FindAll(delegate(Student s)
{
int index = list2.FindIndex(delegate(Student ss)
{
return ss == s;
});
if (index >= )
{
return false;
}
else
{
return true;
}
});
//输出看结果
foreach (var s in listRes)
{
Console.WriteLine("Name=" + s.Name + "; Age=" + s.Age);
} Console.Read();
}
} class Student
{
public int Age
{
get;
set;
} public string Name
{
get;
set;
}
}
}

List删除 重复数据

    // 不能用foreach,因为迭代器是只读的
for (int i = ; i < strs.Count; i++)
{
// 如果第一次出现的位置不等于最后一次出现的位置,则说明该元素不止出现一次
if (strs.IndexOf(strs[i]) != strs.LastIndexOf(strs[i]))
{
strs.RemoveAt(strs.LastIndexOf(strs[i]));
}
}

删除重复

ddd

ddd

ddd

ddd

ddd

ddd

05-11 02:20