using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Xunit;
using LinqStudy;
namespace LinqStudy.Test.LinqToObject
{
///
/// 投影操作符
/// 投影:遍历序列中的元素,将元素由一种类型转换为另一种类型的操作,并返回由转换后元素组成的新序列。
/// 即是:IEnumerable => IEnumerable
///
public class ProjectiveTest
{
#region Select
///
/// Select投影:简单投影,一对一
///
[Fact]
public void Select_Test()
{
// Arrange
var persons = PersonManager.GetPersons();
// Act
var maps = persons.Select(p => p.Age).ToList();
// Assert
Assert.IsType>(maps);
}
///
/// 投影为匿名类
///
[Fact]
public void Select_Anonymous_Test()
{
// Arrange
var persons = PersonManager.GetPersons();
// Act
var maps = persons.Select(p => new { Id = p.Id, Node = $"姓名{p.Name},年龄{p.Age}." }).ToList();
// Assert
Assert.IsNotType>(maps);
}
///
/// 投影传入索引(序号)参数
///
[Fact]
public void Select_Index_Test()
{
var persons = PersonManager.GetPersons();
var maps = persons.Select((query, index) => new KeyValuePair(index, query)).ToList();
var indexs = persons.Select((query, index) => index).ToList();
Assert.IsType>>(maps);
Assert.Equal(0, indexs[0]);
}
#endregion
#region SelectMany
///
/// 将序列的每个元素投影到 IEnumerable 并将结果序列合并为一个序列。
///
///
/// SelectMany:复合投影,一对多,合并多到一个集合。
/// 枚举源序列,将源序列每一项投影为新的集合,合并所有新集合为一个可枚举序列,做为返回值;
/// 提供了将多个 from子句组合起来的功能,它将每个对象的结果合并成单个可枚举序列。
///
[Fact]
public void SelectMany_Test()
{
var employees = new List()
{
new Employee(){Id=1,Name="小明",Emails=new List(){ "abc@163.com", "acd@163.com", "ade@163.com" } },
new Employee(){Id=2,Name="大壮",Emails=new List(){ "bbc@163.com", "bcd@163.com", "bde@163.com" } },
new Employee(){Id=3,Name="周羊",Emails=new List(){ "cbc@163.com", "ccd@163.com", "cde@163.com" } },
new Employee(){Id=4,Name="承承",Emails=new List(){ "dbc@163.com", "dcd@163.com", "dde@163.com" } },
new Employee(){Id=5,Name="东升",Emails=new List(){ "ebc@163.com", "ecd@163.com", "ede@163.com" }},
};
var maps = employees.SelectMany(q => q.Emails).ToList();
Assert.IsType>(maps);
Assert.Equal(15, maps.Count);
}
///
/// 将序列的每个元素投影到 IEnumerable,并将结果序列合并为一个序列。每个源元素的索引用于该元素的投影表。
///
///
/// 添加一个对源枚举的索引而已。索引从0开始,最大为TSource.Count-1
///
[Fact]
public void SelectMany_Index_Test()
{
var employees = new List()
{
new Employee(){Id=1,Name="小明",Emails=new List(){ "abc@163.com", "acd@163.com", "ade@163.com" } },
new Employee(){Id=2,Name="大壮",Emails=new List(){ "bbc@163.com", "bcd@163.com", "bde@163.com" } },
new Employee(){Id=3,Name="周羊",Emails=new List(){ "cbc@163.com", "ccd@163.com", "cde@163.com" } },
new Employee(){Id=4,Name="承承",Emails=new List(){ "dbc@163.com", "dcd@163.com", "dde@163.com" } },
new Employee(){Id=5,Name="东升",Emails=new List(){ "ebc@163.com", "ecd@163.com", "ede@163.com" }},
};
var maps = employees.SelectMany((q, idx) =>
{
q.Emails.Add(idx.ToString());
return q.Emails;
}).ToList();
Assert.IsType>(maps);
Assert.Equal(20, maps.Count);
}
///
/// 将序列的每个元素投影到 IEnumerable,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。
///
///
/// 自定义结果项,类似Cross JOIN
///
[Fact]
public void SelectMany_TCollection_Test()
{
var employees = new List()
{
new Employee(){ Id=1,Name="小明",Emails=new List(){ "a1@163.com", "a2@163.com", "a3@163.com" } },
new Employee(){ Id=2,Name="大壮",Emails=new List(){ "b1@163.com", "b2@163.com", "b3@163.com" } },
new Employee(){ Id=3,Name="周羊",Emails=new List(){ "c1@163.com", "c2@163.com", "c3@163.com" } },
new Employee(){ Id=4,Name="承承",Emails=new List(){ "d1@163.com", "d2@163.com", "d3@163.com" } },
new Employee(){ Id=5,Name="东升",Emails=new List(){ "e1@163.com", "e2@163.com", "e3@163.com" } },
};
var maps = employees.SelectMany((employee) => employee.Emails, (person, email) => new { Name = person.Name, Email = email }).ToList();
Assert.Equal(15, maps.Count);
}
///
/// 将序列的每个元素投影到 IEnumerable,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。
/// 每个源元素的索引用于该元素的中间投影表。
///
///
/// 自定义结果项,类似Cross JOIN
///
[Fact]
public void SelectMany_TCollection_Index_Test()
{
var employees = new List()
{
new Employee(){ Id=1,Name="小明",Emails=new List(){ "a1@163.com", "a2@163.com", "a3@163.com" } },
new Employee(){ Id=2,Name="大壮",Emails=new List(){ "b1@163.com", "b2@163.com", "b3@163.com" } },
new Employee(){ Id=3,Name="周羊",Emails=new List(){ "c1@163.com", "c2@163.com", "c3@163.com" } },
new Employee(){ Id=4,Name="承承",Emails=new List(){ "d1@163.com", "d2@163.com", "d3@163.com" } },
new Employee(){ Id=5,Name="东升",Emails=new List(){ "e1@163.com", "e2@163.com", "e3@163.com" } },
};
var maps = employees.SelectMany
(
(employee, idx) =>
{
return new List() { new Employee() { Id = employee.Id, Name = employee.Name + "_" + idx, Emails = employee.Emails } };
},
(person, email) => new
{
Name = email.Name,
Email = email.Emails
}
)
.ToList();
Assert.Equal(5, maps.Count);
}
#endregion
}
}