
简介
C# 中的 LINQ(Language Integrated Query,语言集成查询)是一组扩展方法,用于对集合进行查询和操作。LINQ 提供了一种统一的方式来查询和操作各种数据源,如数组、集合、数据库、XML 文档等。LINQ 使得开发者可以使用类似 SQL 的语法来查询和操作数据,而不需要关心数据源的具体类型。
本次文章介绍的LINQ to Objects用于查询和操作内存中的对象集合,如数组、列表等。允许我们很灵活地处理数据。
常见的LINQ操作符
1. Where 操作符
Where 操作符用于筛选集合中的元素,基于指定的条件。例如:
// 给定一个整数数组,找出其中的偶数,并按降序排序。
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// 关键字语法
var sorted = from n in numbers
where n % 2 == 0
select n;
//方法语法
var sorted_again = numbers.Where(n => n % 2 == 0);2. Select 操作符
select 操作符用于将集合中的每个元素投影到另一个形式。关键字语句必须以select或group结尾。
// 将每个单次转换成大写
string[] words = { "apple", "pear", "peach", "plum", "kiwi", "grape" };
var upper_words = from word in words select word.ToUpper();
var upper_words_again = words.Select(word => word.ToUpper());3. OrderBy 和 OrderByDescending 操作符
OrderBy 和 OrderByDescending 操作符用于对集合中的元素进行升序或降序排序。
// 排序
int[] numbers = { 5, 1, 9, 3, 7, 2, 8, 4, 6 };
var sorted_numbers = from num in numbers orderby num select num;
var sorted_numbers_again = numbers.OrderBy(num => num);
var sorted_numbers_again_and_again = numbers.Order();
var descending_numbers = from num in numbers orderby num descending select num;
var descending_numbers_again = numbers.OrderByDescending(num => num);
var descending_numbers_again_and_again = numbers.OrderDescending();4. GroupBy 操作符
GroupBy 操作符用于将集合中的元素分组。
// 按第一个字母对单词分组
string[] words = { "apple", "apricot", "banana", "berry", "blueberry", "cherry" };
var grouped_words = from word in words group word by word[0];
var grouped_words_again = words.GroupBy(word => word[0]);
grouped_words.ToList().ForEach(x => Console.WriteLine(String.Join(',', x)));
grouped_words_again.ToList().ForEach(x => Console.WriteLine(String.Join(',', x)));5. Join操作符
join 操作符用于将两个集合根据某个共同的键进行连接。
public static class Program
{
public static void Main()
{
var students = new List<Student>
{
new Student { Id = 1, Name = "Alice", CourseId = 1 },
new Student { Id = 2, Name = "Bob", CourseId = 2 },
new Student { Id = 3, Name = "Charlie", CourseId = 1 }
};
var courses = new List<Course>
{
new Course { Id = 1, Title = "Math" },
new Course { Id = 2, Title = "Science" }
};
var query = from student in students
join course in courses on student.CourseId equals course.Id
select new { StudentName = student.Name, CourseTitle = course.Title };
var query_again = students.Join(courses,
student => student.CourseId,
course => course.Id,
(student, course) => new
{
StudentName = student,
CourseTitle = course.Title
});
}
}
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int CourseId { get; set; }
}
public class Course
{
public int Id { get; set; }
public string Title { get; set; }
}
常见操作
过滤和排序
给定一个整数数组,找出其中的偶数,并按降序排序。
输入:int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
输出:{ 10, 8, 6, 4, 2 }
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var ans = numbers.Where(x => x % 2 == 0).OrderDescending();
Console.WriteLine(String.Join(',', ans));转换和筛选
给定一个字符串数组,将每个字符串转换为大写,并筛选出长度大于3的字符串。
输入:string[] words = { "apple", "pear", "peach", "plum", "kiwi", "grape" };
输出:{ "APPLE", "PEAR", "PEACH", "PLUM", "GRAPE" }
string[] words = { "apple", "pear", "peach", "plum", "kiwi", "grape", "dog" };
var ans = words.Select(x => x.ToUpper()).Where(x => x.Length > 3);
Console.WriteLine(String.Join(',', ans));分组和聚合
给定一个字符串数组,按照字符串的首字母分组,并计算每个组中的字符串数量。
输入:string[] words = { "apple", "apricot", "banana", "berry", "blueberry", "cherry" };
输出:
a: 2
b: 3
c: 1string[] words = { "apple", "apricot", "banana", "berry", "blueberry", "cherry" };
Dictionary<string, int> ans = words.GroupBy(w => w[0].ToString()).ToDictionary(g => g.Key, g => g.Count());
foreach (var item in ans)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}连接和投影
给定两个集合,一个是员工列表,另一个是部门列表。根据员工所属的部门ID,将员工和部门连接起来,并选择员工的姓名和部门名称。
输入:
class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public int DepartmentId { get; set; }
}
class Department
{
public int Id { get; set; }
public string Name { get; set; }
}
List<Employee> employees = new List<Employee>
{
new Employee { Id = 1, Name = "Alice", DepartmentId = 2 },
new Employee { Id = 2, Name = "Bob", DepartmentId = 1 },
new Employee { Id = 3, Name = "Charlie", DepartmentId = 2 }
};
List<Department> departments = new List<Department>
{
new Department { Id = 1, Name = "HR" },
new Department { Id = 2, Name = "Engineering" }
};
输出:
Alice - Engineering
Bob - HR
Charlie - Engineeringvar ans = employees.Join(departments, e => e.DepartmentId, d => d.Id, (e, d) => new { Name = e.Name, Department = d.Name })
.ToDictionary(x => x.Name, x => x.Department);
foreach (var item in ans)
{
Console.WriteLine($"{item.Key} - {item.Value}");
}嵌套查询
给定一个员工列表,每个员工有一个技能列表。找出所有掌握“C#" 技能的员工,并返回这些员工的姓名和技能列表。
输入:
class Employee
{
public string Name { get; set; }
public List<string> Skills { get; set; }
}
List<Employee> employees = new List<Employee>
{
new Employee { Name = "Alice", Skills = new List<string> { "C#", "SQL" } },
new Employee { Name = "Bob", Skills = new List<string> { "Java", "Python" } },
new Employee { Name = "Charlie", Skills = new List<string> { "C#", "JavaScript" } }
};
输出:
Name: Alice, Skills: C#, SQL
Name: Charlie, Skills: C#, JavaScriptvar ans = employees.Where(e => e.Skills.Contains("C#")).ToDictionary(e => e.Name, e => e.Skills);
foreach (var item in ans)
{
Console.WriteLine($"Name: {item.Key}, Skills: {string.Join(", ", item.Value)}");
}
评论区