【类库】容器对象(List、DataTable、 DataView、Dictionary)
首先申明一下,写此博文的目的是纪录一下,知识都是现成的,只是整理一下,为了让自己更容易看懂,比在其他地方更容易明白。因为它们太常用了,不忍心每次都去用那么长的时间查看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
【类库】容器对象(List、DataTable、 DataView、Dictionary)的更多相关文章
- 【Spring】手动获取spring容器对象时,报no qualifying bean of type is defined
手动获取容器对象时,报no qualifying bean of type is defined, 经过调查,发现手动获取的时候,该类所在的包必须经过spring容器初始化. 1.SpringConf ...
- C++ 容器对象vector和list 的使用
在<<c++ primer>>第四版Exercise Section 9.3.4 的Exercise 9.20 是这样的一道题目:编写程序判断一个vector<int&g ...
- 获取spring容器对象方法和原因
为什么要获取Spring容器对象:拿到spring容器对象后,你就可以用spring管理的bean了,拿到bean,自然可以使用bean的方法,场景:比如jsp页面.通过注解是无法注入bean的,在开 ...
- 配置Spring的用于初始化容器对象的监听器
<!-- 配置Spring的用于初始化容器对象的监听器 --> <listener> <listener-class>org.springframework.web ...
- javascript客户端遍历控件与获取父容器对象
javascript客户端遍历控件与获取父容器对象示例代码 1,遍历也面中所有的控件function findControlAll() { var inputs=document. ...
- 将Spring容器跟随系统启动并获取容器对象
将Spring容器随系统启动的方法: 在web.xml中配置监听器,监听的对象为ContextLoaderListener <listener> <listener-class> ...
- 条目七《如果容器中包含了通过new操作创建的指针,切记在容器对象析构前将指针delete掉》
如果容器中包含了通过new操作创建的指针,切记在容器对象析构前将指针delete掉 在STL中容器是智能的,可以在容器销毁时自动调用容器里对象的析构函数来销毁容器存储的对象. STL的容器虽然比较智能 ...
- DataSet,DataTable,DataView、DataRelation
一.创建Dataset和DataTable DataSet ds = new DataSet();//DataSetName默认为"NewDataSet" DataTable ta ...
- ADO.NET对象之 DataTable
ADO.NET可以在与数据库断开连接的方式下通过DataSet或DataTable对象进行数据处理,当需要更新数据时才重新与数据源进行连接,并更新数据源. DataTable对象表示保存在本机内存中的 ...
随机推荐
- C/C++浮点数在内存中的存储方式
一.内存表示 任何数据在内存中都是以二进制的形式存储的,浮点数的表示是把一个数的有效数字和数的范围在计算机的一个存储单元中分别予以表示,数的小数点位置随比例因子的不同而在一定范围内自由浮动.如下图是3 ...
- percona教程:MySQL GROUP_CONCAT的使用
percona有一篇blog: The power of MySQL GROUP_CONCAT 比较详细地介绍了GROUP_CONCAT函数的用法.简单地翻译了一下. 假设你有4名工程师,这周他们为6 ...
- Sublime Text 技巧
让sublime text2支持中文 安装Sublime Package Control 在Sublime Text 2上用Ctrl+-打开控制台并在里面输入以下代码,Sublime Text 2就会 ...
- Xamarin.Android VSTS 持续集成
这些天做了一个基于 VSTS 的 Xamarin.Android的持续集成,这里分享下 Build Agent 环境需求 DotNetFramework msbuild visualstudio An ...
- 《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果(速度可实时)
最新的效果见 :http://video.sina.com.cn/v/b/124538950-1254492273.html 可处理视频的示例:视频去雾效果 在图像去雾这个领域,几乎没有人不知道< ...
- 模-数(A/D)转换器
一.A/D转换的基本原理 在一系列选定的瞬间对模拟信号进行取样,然后再将这些取样值转换成输出的数字量,并按一定的编码形式给出转换结果. 整个A/D转换过程大致可分为取样.量化.编码三个过程.二.取样- ...
- 【CSS】使用盒模型
盒子是CSS中的基础概念,我们需要使用它来配置元素的外观以及文档的整体布局. 1. 为元素应用内边距 应用内边距会在元素内容和边距之间添加空白.我们可以为内容盒的每个边界单独设置内边距,或者使用 pa ...
- 移位操作(>>、<<)
public static void main(String[] args) { /** 移位就是二进制的数往左或右移动,因为接近计算机底层,所以速度比较快 * 8 4 2 1 * * 7 化为二进制 ...
- LL(1)算法
编译原理的语法分析中一个入门的算法就是LL(1)算法了,这里做一个总结.首先比较重要的是FIRST集和FOLLOW集合的生成. 先上个例子吧: 首先说一下FIRST集的生成,这个就要看产生式右部对应的 ...
- hdoj 2075 A|B?
A|B? Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...