1. Consider the following string array.Ans:
string[] countries = { "India", "US", "UK", "Canada", "Australia" };
We want to combine all these strings into a single comma separated string. The output of the program should be as shown below.
India, US, UK, Canada, Australia
string result = countries.Aggregate((a, b) => a + ", " + b);
*Print all the ProductNames in comma separated list of a given category
string productNames = db.Categories.Where( x=> x.categoryId ==1)
.SelectMany(x=> x.Products.Select(p=>p.ProductName)).ToArray()
.Aggregate( (a,b) => a + ", " + b) );
2. Consider the following integer array
int[] Numbers = { 2, 3, 4, 5
};
Compute the product of all numbersint result = Numbers.Aggregate((a, b) => a * b);
3. What is a Predicate?
A predicate is a function to test each element for a condition
In the following example, the Lambda expression (num => num % 2 == 0) runs for each element in List<int>. If the number is divisible by 2, then a boolean value true is returned otherwise false.
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IEnumerable<int>
evenNumbers = numbers.Where(num => num
% 2 == 0);
As shown in debug mode during its execution,the predicate expects an int input parameter and returns a boolean value. The lambda expression that is passed operates on an int type and should return boolean, otherwise there will be compile time error.
So this means, the line below from the above example
IEnumerable<int>
evenNumbers = numbers.Where(num => num
% 2 == 0);
can be rewritten as shown below
Func<int, bool> predicate = i =>
i % 2 == 0;
IEnumerable<int>
evenNumbers = numbers.Where(predicate);Or like below:
IEnumerable<int> evenNumbers = numbers.Where(num => IsEven(num));
public static bool IsEven(int number)
{
if (number % 2 == 0)
{
return true;
}
else
{
return false;
}
}
The int parameter of the predicate function represents the index of the source element
The following program prints the index position of all the even numbers
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IEnumerable<int>
evenNumberIndexPositions = numbers
.Select((num, index)
=> new { Number =
num, Index = index })
.Where(x => x.Number
% 2 == 0)
.Select(x => x.Index);
foreach (int evenNumber in evenNumberIndexPositions)
{
Console.WriteLine(evenNumber);
}
SelectMany Operator belong to Projection Operators category. It is used to project each element of a sequence to an IEnumerable<T> and flattens the resulting sequences into one sequence.
Consider the following Student class. Subjects property in this class is a collection of strings.
public class Student
{
public string Name
{ get; set;
}
public string Gender
{ get; set;
}
public List<string> Subjects { get; set; } public static List<Student> GetAllStudetns()
{
List<Student> listStudents
= new List<Student>
{
new Student
{
Name = "Tom",
Gender = "Male",
Subjects = new List<string> { "ASP.NET",
"C#" }
},
// add few more students like this.};
return listStudents;
}
Projects all subject strings of a given a student to an IEnumerable<string>
IEnumerable<string> allSubjects = Student.GetAllStudetns().SelectMany(s => s.Subjects);
Output:
Rewrite above, using SQL like syntax. When using SQL like syntax style, we don't use SelectMany, instead we will have an additional from clause, which will get it's data from the results of the first from clause.
IEnumerable<string>
allSubjects = from student
in Student.GetAllStudetns()
from subject in student.Subjects
select subject;
Projects each string to an IEnumerable<char>
string[] stringArray =
{
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"0123456789"
};
IEnumerable<char>
result = stringArray.SelectMany(s => s);
foreach (char c in
result)
{
Console.WriteLine(c);
}Sql like syntax:
IEnumerable<char>
result = from s in stringArray
from c in
s
select c;Selects only the distinct subjects
IEnumerable<string>
allSubjects = Student.GetAllStudetns()
.SelectMany(s
=> s.Subjects).Distinct();
using SQL like syntax.
IEnumerable<string>
allSubjects = (from student
in Student.GetAllStudetns()
from subject in student.Subjects
select subject).Distinct();
var result = Student.GetAllStudetns().SelectMany(s
=> s.Subjects, (student, subject) =>
new { StudentName = student.Name, Subject = subject
});
foreach (var v in
result)
{
Console.WriteLine(v.StudentName + " - " + v.Subject);
}
using SQL like syntax.
var result = from
student in Student.GetAllStudetns()
from subject in student.Subjects
select new { StudnetName = student.Name,
Subject = subject };
LINQ GROUP BY:
GroupBy operator belong to Grouping Operators category. This operator takes a flat sequence of items, organize that sequence into groups (IGrouping<K,V>) based on a specific key and return groups of sequences.
In short, GroupBy creates and returns a sequence of IGrouping<K,V>
Consider Employee class
public class Employee
{
public int ID
{ get; set;
}
public string Name
{ get; set;
}
public string Gender
{ get; set;
}
public string Department
{ get; set;
}
public int Salary
{ get; set;
}public static List<Employee> GetAllEmployees()
{
return new List<Employee>()
{
new Employee { ID = 1, Name = "Mark", Gender = "Male",
Department = "IT", Salary = 45000
}
// add few more employees..
}
}
}
Example 1: Get Employee Count By Department
var employeeGroup = from
employee in Employee.GetAllEmployees()
group employee by employee.Department;
foreach (var group in employeeGroup)
{
Console.WriteLine("{0} -
{1}", group.Key, group.Count());
}
Example 2: Get Employee Count By Department and also each employee and department name
var employeeGroup = from
employee in Employee.GetAllEmployees()
group employee by employee.Department;
foreach (var group in employeeGroup)
{
Console.WriteLine("{0} -
{1}", group.Key, group.Count());
Console.WriteLine("----------");
foreach (var employee
in group)
{
Console.WriteLine(employee.Name + "\t" + employee.Department);
}
Console.WriteLine(); Console.WriteLine();
}
Example 3:
Get Employee Count By Department and also each employee and department
name. Data should be sorted first by Department in ascending order and
then by Employee Name in ascending order.
Output:
var employeeGroup = from
employee in Employee.GetAllEmployees()
group employee by employee.Department into eGroup
orderby eGroup.Key
select new
{
Key = eGroup.Key,
Employees = eGroup.OrderBy(x
=> x.Name)
};
foreach (var group in employeeGroup)
{
Console.WriteLine("{0} -
{1}", group.Key, group.Employees.Count());
Console.WriteLine("----------");
foreach (var employee
in group.Employees)
{
Console.WriteLine(employee.Name + "\t" + employee.Department);
}
Console.WriteLine(); Console.WriteLine();
}
Output:
In LINQ, an anonymous type is usually used when we want to group by multiple keys.
Consider the Employee Class used above.
Example 1: Group employees by Department and then by Gender. The employee groups should be sorted first by Department and then by Gender in ascending order. Also, employees within each group must be sorted in ascending order by Name.
var employeeGroups = Employee.GetAllEmployees()
.GroupBy(x => new { x.Department, x.Gender })
.OrderBy(g => g.Key.Department).ThenBy(g
=> g.Key.Gender)
.Select(g => new
{
Dept = g.Key.Department,
Gender = g.Key.Gender,
Employees = g.OrderBy(x =>
x.Name)
});
foreach(var group in employeeGroups)
{
Console.WriteLine("{0}
department {1} employees count = {2}",
group.Dept, group.Gender, group.Employees.Count());
Console.WriteLine("--------------------------------------------");
foreach (var employee
in group.Employees)
{
Console.WriteLine(employee.Name + "\t" + employee.Gender
+ "\t"
+ employee.Department);
}
Console.WriteLine(); Console.WriteLine();
}
Output:
Example 2: Rewrite Example 1 using SQL like syntax
var employeeGroups = from
employee in Employee.GetAllEmployees()
group employee by new
{
employee.Department,
employee.Gender
} into eGroup
orderby eGroup.Key.Department ascending,
eGroup.Key.Gender ascending
eGroup.Key.Gender ascending
select new
{
Dept = eGroup.Key.Department,
Gender = eGroup.Key.Gender,
Employees = eGroup.OrderBy(x
=> x.Name)
};
0 comments:
Post a Comment