You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

414 lines
12 KiB
C#

6 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Xunit;
6 years ago
using System.Collections.Immutable;
6 years ago
namespace LinqStudy.Test.LinqToObject
{
/// <summary>
6 years ago
/// Sets 集合操作符
/// 注意:集合操作为 “延迟执行”数据源为null时均引发异常。
6 years ago
/// </summary>
public class SetsTest
{
#region Distinct
/// <summary>
/// Distinct元素去重;延迟执行。
/// 注意:值类型可以直接去重;引用类型比较的是引用而不是对象本身的属性等,可以提供自定义比较器。
/// </summary>
[Fact]
public void Distinct_Test()
{
List<int> array = new List<int>() { 1, 2, 2, 3, 3, 3 };
var distinctItem = array.Distinct();
var expected = new List<int>() { 1, 2, 3 };
Assert.Equal(expected, distinctItem);
}
/// <summary>
/// 引用类型:剔除同一个引用的重复项。
/// </summary>
[Fact]
public void Distinct_Reference_Yes_Test()
{
var p1 = new Person() { Id = 2, Name = "小龙女", Age = 28 };
var p2 = new Person() { Id = 4, Name = "杨过", Age = 32 };
List<Person> peoples = new List<Person>();
peoples.Add(p1);
peoples.Add(p2);
//添加对同一对象的多次引用
peoples.Add(p1);
peoples.Add(p2);
var totalCount = peoples.Count();
var distinctCount = peoples.Distinct().Count();
Assert.Equal(4, totalCount);
Assert.Equal(2, distinctCount);
}
[Fact]
public void Distinct_Reference_No_Test()
{
List<Person> peoples = new List<Person>()
{
new Person() { Id = 1, Name = "小龙女", Age = 28 },
new Person() { Id = 1, Name = "小龙女", Age = 28 },
};
//虽然1、2两项对象属性完命相同但是两个不同的对象(new两次),所以不是“重复项”
//去重后仍然是2项
var distinctCount = peoples.Distinct().Count();
Assert.Equal(2, distinctCount);
}
/// <summary>
/// 延迟执行
/// </summary>
[Fact]
public void Distinct_Daley_Test()
{
List<int> array = new List<int>() { 1, 2, 2, 3, 3, 3 };
var distinctItem = array.Distinct();
array.Add(5);
var expected = new List<int>() { 1, 2, 3, 5 };
Assert.Equal(expected, distinctItem);
}
/// <summary>
/// 重载:自定义比较器
/// </summary>
[Fact]
public void Distinct_compare_Test()
{
List<Person> peoples = new List<Person>()
{
new Person(){ Id=1, Name="小龙女", Age=28},
new Person(){ Id=1, Name="我不是龙女", Age=68},
};
var distinctItem = peoples.Distinct(new PersonEqualityComparerById());
//虽然两项只有Id属性相等其它属性均不同
//但是因为自定义比较器内部只比较Id即只要Id相同就认为同一对象。
//所以去重后,只有一项(第一项,第二项被认为是重复项,被去除)。
var distinctCount = distinctItem.Count();
var expected = 1;
Assert.Equal(expected, distinctCount);
}
#endregion
#region Union
///<summary>
/// Union:取两个序列的并集,并去除重复项。
/// 与SQL比较相似Concat不去除重复项。
///</summary>
[Fact]
public void Union_Test()
{
var p1 = new Person() { Id = 1, Name = "杨过", Age = 32 };
var p2 = new Person() { Id = 2, Name = "小龙女", Age = 28 };
6 years ago
var p3 = new Person() { Id = 3, Name = "云花公主", Age = 16 };
6 years ago
List<Person> peoples1 = new List<Person>()
{
p1,
p2,
};
List<Person> peoples2 = new List<Person>()
{
p1,
p3,
};
var act = peoples1.Union(peoples2);
//因为"杨过"是重复的所有总共有3项
var totalCount = act.Count();
Assert.Equal(3, totalCount);
}
///<summary>
/// Union: 对同一数据源两次查询后两次结果Union
/// 注意:同一数据源多次查询形成的序列项,均是对同一对象的引用。
/// 项里保存的是引用地址,非对象本身。
///</summary>
[Fact]
public void Union_UseQuery_Test()
{
List<Person> peoples = new List<Person>()
{
new Person(){ Id=1, Name="张三丰", Age=230},
new Person(){ Id=2, Name="小龙女", Age=28},
6 years ago
new Person(){ Id=3, Name="云花公主", Age=16},
6 years ago
new Person(){ Id=4, Name="杨过", Age=32},
};
var peoples1 = peoples.Where(q => q.Id <= 3);
var peoples2 = peoples.Where(q => q.Age < 230);
var act = peoples1.Union(peoples2);
//前3项 + 后3项- 重复2项=4项
var totalCount = act.Count();
Assert.Equal(4, totalCount);
}
///<summary>
/// Union重载: camparer
///</summary>
[Fact]
public void Union_camparer_Test()
{
var p1 = new Person() { Id = 1, Name = "杨过", Age = 32 };
var p2 = new Person() { Id = 2, Name = "小龙女", Age = 28 };
var p3 = new Person() { Id = 2, Name = "我非龙女", Age = 77 };
List<Person> peoples1 = new List<Person>()
{
p1,
p2,
};
List<Person> peoples2 = new List<Person>()
{
p1,
p3,
};
var act = peoples1.Union
(
peoples2,
new PersonEqualityComparerById()
)
.ToList();
//虽然P2和p3只有Id相同其它不同但自定义比较只看Id所以P2和p3被认为是同一个对象。
//结果集为p1+p2
var totalCount = act.Count();
Assert.Equal(2, totalCount);
}
///<summary>
/// 异常ArgumentNullException
///</summary>
[Fact]
public void Union_ArgumentNullException_Test()
{
List<Person> peoples1 = null;
List<Person> peoples2 = null;
Action act = () => peoples1.Union
(
peoples2
);
Assert.Throws<ArgumentNullException>(act);
}
#endregion
6 years ago
#region Intersect
///<summary>
/// Intersect: 取交集
///</summary>
[Fact]
public void Intersect_Test()
{
var p1 = new Person() { Id = 1, Name = "杨过", Age = 32 };
var p2 = new Person() { Id = 2, Name = "小龙女", Age = 28 };
var p3 = new Person() { Id = 3, Name = "云花公主", Age = 16 };
List<Person> peoples1 = new List<Person>()
{
p1,p2,
};
List<Person> peoples2 = new List<Person>()
{
p1,p3,
};
var intesectItem = peoples1.Intersect(peoples2);
var itemCount = intesectItem.Count();
Assert.Equal(1, itemCount);
}
///<summary>
/// 引用类型:使用
///</sumaary>
[Fact]
public void Intersect_Reference_Test()
{
List<Person> peoples1 = new List<Person>()
{
new Person(){ Id=1, Name="杨过", Age=32},
new Person(){ Id=2, Name="小龙女", Age=28},
};
List<Person> peoples2 = new List<Person>()
{
new Person(){ Id=2, Name="小龙女", Age=28},
new Person(){ Id=3, Name="云花公主", Age=16},
};
//虽然两个“小龙女”属性相同,但不是一个对象,没有交集。
var intesectItem = peoples1.Intersect(peoples2);
Assert.Empty(intesectItem);
}
///<summary>
/// 重载:自定义比较器 comparer
///</sumaary>
[Fact]
public void Intersect_comparer_Test()
{
List<Person> peoples1 = new List<Person>()
{
new Person(){ Id=1, Name="杨过", Age=32},
new Person(){ Id=2, Name="小龙女", Age=28},
};
List<Person> peoples2 = new List<Person>()
{
new Person(){ Id=2, Name="小龙女", Age=28},
new Person(){ Id=3, Name="云花公主", Age=16},
};
//虽然两个“小龙女”属性相同,但不是一个对象,没有交集。
var intesectItem = peoples1.Intersect(peoples2, new PersonEqualityComparerById());
var intesctItemName = intesectItem.First().Name;
Assert.Equal("小龙女", intesctItemName);
}
#endregion
#region Intersect
///<summary>
/// Except: 从一个序列中排除另一个序列中的项。
///</summary>
[Fact]
public void Except_Test()
{
var p1 = new Person() { Id = 1, Name = "杨过", Age = 32 };
var p2 = new Person() { Id = 2, Name = "小龙女", Age = 28 };
var p3 = new Person() { Id = 3, Name = "云花公主", Age = 16 };
List<Person> peoples1 = new List<Person>()
{
p1,p2,
};
List<Person> peoples2 = new List<Person>()
{
p1,p3,
};
var exceptItem = peoples1.Except(peoples2);
var itemName = exceptItem.First().Name;
Assert.Equal("小龙女", itemName);
}
///<summary>
/// 引用类型:使用
///</sumaary>
[Fact]
public void Except_Reference_Test()
{
List<Person> peoples1 = new List<Person>()
{
new Person(){ Id=1, Name="杨过", Age=32},
new Person(){ Id=2, Name="小龙女", Age=28},
};
List<Person> peoples2 = new List<Person>()
{
new Person(){ Id=2, Name="小龙女", Age=28},
new Person(){ Id=3, Name="云花公主", Age=16},
};
var exceptItem = peoples1.Except(peoples2);
var itemCount = exceptItem.Count();
Assert.Equal(2, itemCount);
}
///<summary>
/// 重载:自定义比较器 comparer
///</sumaary>
[Fact]
public void Except_comparer_Test()
{
List<Person> peoples1 = new List<Person>()
{
new Person(){ Id=1, Name="杨过", Age=32},
new Person(){ Id=2, Name="小龙女", Age=28},
};
List<Person> peoples2 = new List<Person>()
{
new Person(){ Id=2, Name="小龙女", Age=28},
new Person(){ Id=3, Name="云花公主", Age=16},
};
var exceptItem = peoples1.Except(peoples2, new PersonEqualityComparerById());
var iexcepItemName = exceptItem.First().Name;
Assert.Equal("杨过", iexcepItemName);
}
6 years ago
#endregion
6 years ago
6 years ago
#region 串联操作:Concat
6 years ago
///<summary>
6 years ago
/// Concat将两个序列合并成一个序列不去重。与Union不同。
6 years ago
///<summary>
6 years ago
[Fact]
public void Concat_Test()
6 years ago
{
6 years ago
List<Person> peoples1 = new List<Person>()
6 years ago
{
new Person(){ Id=2, Name="小龙女", Age=28},
new Person(){ Id=4, Name="杨过", Age=32},
};
6 years ago
List<Person> peoples2 = new List<Person>()
6 years ago
{
new Person(){ Id=2, Name="小龙女", Age=28},
new Person(){ Id=3, Name="云花公主", Age=16},
};
6 years ago
var concatAct = peoples1.Concat(peoples2);
var totalCount = concatAct.Count();
6 years ago
6 years ago
Assert.Equal(4, totalCount);
6 years ago
}
#endregion
6 years ago
}
}