think in linq

Post on 20-Mar-2017

111 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Think in LINQ

Introduction to LINQ to Objects

Sudipta Mukherjee

What shall we talk about?

• Why bother about LINQ?• What’s the origin?• How it works?• Introduction to LINQPad• Some LINQ Operators • Demos• Q & A

Slides are designed for self study at a later

stage also.

So if it seems really long. That’s ok.

Disclaimer

Why bother to learn LINQ ? What can it do for us?

One more step close to conceptWhile you are

expressing your intent by loops you are not only telling

what you want done, but you are giving

painful detail of how you want it done. So it is very difficult for the compiler to emit

high performance code using multiple

processors.

In LINQ you tell WHAT you want, not HOW you want it get

done.

This makes for compilers happy and it can make the code

parallel by using multiple processors

It can query anythingXML/JSON

Database

Objects

What have you!

LINQ

XPath SQL/No-SQL

Loop/If/Else Something

It’s about time we care

• Computer processor speed is stagnated• We won’t get faster processor• We will get more of them• Need Parallelism• Functional approach is good for parallel processing as that’s side-effect free.

Where did it came from? Who are the people behind it?When did it become part of .NET ? Where are we going with this ?

When was LINQ born?

2008 / VS 2008

Roslyn / Compiler-as-a-Service Shipping with C# 5.0

Where are we going?

• Asynchronous apps is the future

• Roots of LINQ gave us a new language

Paradigm Shift?

• C# is bringing best of all worlds • C# is statically typed

It is a good sign

40 years ago 1972

40 years after2012

32 keywords changed the world for ever

60 keywords changed the world for ever

yet again

C programming language changed our notion about

programming

LINQ Changed how we interact with data

How it works?

Open for extension, Closed for modification.

• LINQ to Objects is a collection of extension methods declared on IEnumerable<T>

• So all collections get to use these extension methods

• These extension methods are called LINQ Standard Query Operators (LSQO in short)

• You can define your own LSQO

All LINQ Standard Query Operators

All LSQOs

What’s LINQ?

• Language Integrated Query• Uses Method chaining• Built by Extension Methods • Deeply integrated in the .NET framework

Little Jargons

• Extension Method– A static method of a static class that let you

extend the behavior of the class. • Lambda Expression

– An inline/concise (if you will) representation of a function

• Functor– A place holder for functions

Extension methods

Extension methods show up with a little down blue arrow. This distinguishes them from native methods

How to declare a lambda expression?

Grammar • (variables involved separated by comma ) => (expression involving the variables)

[Example] (customer => customer.City == “London”)

This is also an unary predicate

Declaring a functor

• Use Func<…> • There are several overloads. • Func<int,bool> matches any function that takes

an int and returns a bool• Func<string,string,int> matches any function that

takes two strings as input and returns an integer. • There are 17 overloaded version. That’s a lot. • The last one is the return type

LINQPad – Your C# Snippet Editor

It is beyond LINQ• C# Snippet compiler• F# Snippet compiler• Test External APIs

http://www.linqpad.net/

Most of today’s demo are shown in LINQPad

LINQ Operators (that we shall cover)

• Restriction Operators• Projection Operators• Partitioning Operators• Set Operators• Sorting Operators• Element Operators• Casting Operators• Quantification Operators

Restriction Operators

Where Distinct

Where

• Create a query running which will return those where the given condition is true.

//Return all customers who are from “London” Customers.Where ( c => c.City == “London”)

Distinct

• Create a query running which will remove duplicate elements from the source collection; if present.

//Return all unique customer cities cutomerCities.Distinct();

Projection/ConversionTable # 1

Sam | Smith | 25Lori | Smith | 23

View #1

Sam SmithLori Smith

View #2

Sam 25Lori 23

Select

SelectMany

ToList

ToArray

ToLookupToDictionar

y

Select• Create a query running which will project the

elements of the collection is a way mentioned in the lambda expression provided.

Customers.Select( c => c.City) //Project customer city

Customer City

Sam London

Danny Paris

City

London

Paris

SelectMany• Create a query, that when executed projects

all value elements in an associative container, a dictionary for example

//Returns all states for all countries• countryStates.SelectMany ( c => c.Value)

ToList

• Create a query that when executed projects the result of the query to a strongly typed list.

//Projects orders to a strongly typed list Orders.Where(order => order.Amount > 200).ToList();

ToArray

• Create a query that when executed projects the result of the query to a strongly typed array.

//Projects the result of the query to an array Orders.Where(order => order.Amount >

200).ToArray();

ToDictionary

• Projects the result of a query to a dictionary. User have to define the key using the lambda expression.

//Segregating a list of names in two lists, boy name

//lists and girl name lists. nameList1.ToDictionary (c => c,c=>boys.Contains(c)?"boy":"girl");

ToLookup

• Create a query that when executed creates a lookup table.

//Creating a lookup of unique domain names• string emails =

"a@b.com,c@b.com,c2@b.com,c233@d.com"; emails.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)

.Select(c => c) .ToLookup(c => c.Substring(c.IndexOf('@') +

1).Trim())•

Partitioning Opeartors

Take TakeWhile

Skip SkipWhile

Take

• Create a query that when executed returns only the first N entries mentioned as parameter.

//Take first 10 orders

Orders.Take(10);

TakeWhile

• Create a query that when executed returns the first N elements from the source collection as long as the condition passed as lambda expression is met.

//Take orders from start as long as order amount is

//less than 100. Orders.TakeWhile(c => c.Amount < 100);

Skip

• Create a query that when run, skips the first N elements and return the rest.

//Returns all orders saving the first one. Orders.Skip(1);

SkipWhile

• Create a query that when run, skips the first few elements from the source collection as long as the condition, passed as lambda expression is met.

//Skip orders if the are delivered Orders.SkipWhile(ord => ord.Delivered);

Set Operators

Union

Intersect

Except

Intersect

• Creates a query, that when run returns values from the intersect of two given sets.

//Find intersection of two collection listA.Intersect(setB);

• Not in-place unlike IntersectWith()

Union

• Creates a query that when run returns the union of two given sets

//Returns union of two collections listA.Union(setB);

Except

• Creates a query that when run returns the elements present in the calling set object but not in the argument set.

//Returns elements that are in listA //but not in listB• listA.Except(setB);

Sorting Operators

OrderBy

ThenBy

OrderByDescending

ThenByDescending

OrderBy

• Use to sort a collection by some field of the elements. Say sort a collection of Employees by their age.

//sort all employees by their age employees.OrderBy(employee => employee.Age);

OrderByDescending

• Same as OrderBy, just that the order will be descending.

//sorts all employees in descending order of age employees.OrderByDescending(employee =>

employee.Age);

ThenBy

• Once you have sorted the source collection using OrderBy, you can use ThenBy to sort it again by another field. Cascaded OrderBy() calls is redundant. Only the last call applies.

Employees.OrderBy(employee => employee.Age)//order by age.ThenBy(employee => employee.Salary)//then by

salary;

ThenByDescending

• Same as ThenBy, just that it sorts in descending order.

Employees.OrderBy(employee => employee.Age)//order by age.ThenByDescending(employee => employee.Salary)//then by descending

salary;

Element Operators

First

Last

ElementAtElementAtOrDefaul

t

DefaultIfEmpty

Count LongCount

FirstOrDefault

LastOrDefault

First

• Return the first element or the first element matching the condition passed as lambda expression or the first one if nothing is passed.

//Returns the first order in the listOrder firstOrder = Orders.First(); //Returns the first order coming from BangaloreOrder = Orders.First(order => order.City ==

“Bangalore”);

Last

• Return the last element from the source collection or the last element matching the given condition passed as lambda expression

//Returns the last orderOrder = Orders.Last(); //Returns the last order coming from BangaloreOrder = Orders.Last(order => order.City ==

“Bangalore”);

Count

• Returns the count of elements in the source collection

//Returns the count of orders int totalOrders = Orders.Count(); //Returns the count of orders from Paris int totalOrders = Orders.Count(o => o.City ==

“Paris”);

LongCount

• Returns the count of the source collection. However this one wraps the result as a long rather than an integer. So the range of value is higher. Advised to avoid unless really needed.

long totalOrders = Orders.LongCount();//avoid using

ElementAt• Returns the element at a given index. Advised

not to use on collections that natively don’t support indexing like IDictionary Implementations.

//indexing starts at 0. So 10th element is at 9th Order tenthOrder = Orders.ElementAt(9);

ElementAtOrDefault

• If there is no element found at the given index, this operator returns the default value for the data type of the given collection. For example for an integer collection it would return 0. For classes it returns null.

//If there is no 10th element set the default value. Order tenthOrder = Orders.ElementAtOrDefault(9);

Casting Operators

Cast OfType

AsEnumerable

AsEnumerable• Wraps all the elements in a strongly typed

source collection of type in an IEnumerable<T>. This is used to continue the pipe line.

//strongly typed List<Order> orders = GetOrders(Yesterday); //loosely typed IEnumerable<Order> iOrders = orders.AsEnumerable(); //strongly typed again orders = iOrders.ToList();

Cast• Cast all elements in the source collection to

the given type; if possible.

List<Match> matches = //returning a MatchCollection with all matches Regex.IsMatch(“ACGTACAGGACGA”, “CG”) //casting it to a IEnumerable<Match> instance .Cast<Match>()

//Projecting the result to a list .ToList();

OfType• Extracts elements from the source collection

that are of the given type.

//Extract only the employees from a list of employees

IEnumerable<Developer> devs = allEmployees.OfType<Developer>();

Create values

Repeat

Range

Empty

Empty

• Creates an empty sequence

//Creates an empty sequenceEnumerable.Empty();

Range

• Creates a range of values from given range

//Creates a range from 1 to 100 Enumerable.Range(1,100);

Repeat

• Create N copies of the given object.

//Creates a list of strings with the same string //repeated. List<string> voices = Enumerable .Repeat(“World is not enough”,10) //projecting the list to a strongly typed

list. .ToList();

Quantification Operators

Any

Single

SingleOrDefault

Any

• Create a query running which will return true if there is at least one element satisfying the given condition.

//Checks if there is any customer form “London” or not

Customers.Any ( c => c.City == “London”)

Single

• Create a query running which will return the single element matching the condition. If no such element is found, it throws exception

//Finds the only customer from NYC Customers.Single( c => c.City == “NYC”)

SingleOrDefault

• Create a query running which will return the single element matching the condition. If no such element is found, it returns the default value.

//Finds the only customer from London //if no such element is found, it returns default //in this case it is null. Customers.SingleOrDefault ( c => c.City ==

“London”)

Pull the zipper

Zip

Mr.

Mrs.

Master.

Ms.

Sam

Jen

Ben

Jace

Smith

Mr. Sam Smith

Zip• Puts together two entities from two different

lists at the same index and creates a collection of the concatenated results.

//Creates full name with salutation for Smith familystring[] salutations =

{"Mr.","Mrs.","Master.","Ms."};string[] firstNames = {"Sam","Jen","Ben","Jace"};string lastName = "Smith";Salutations .Zip(firstNames, (sal , first) => sal + " " +

first) .ToList() .ForEach(name => Console.WriteLine(name +

lastName));

Some example LINQ ScriptsExciting but not really from our domain

Spam E-mail domain Indexing

Output

b.com:3d.com:1

Finding all Winning Paths in Tic-Tac-Toe

• For an arbitrary board size n, for 3x3 , n = 3

Finding all Horizontal Paths

Expanding LINQ Query over multiple lines enable

Debugging

LINQ to Flat file Provider

See how Func<> is being used

Using LINQ with .NET Reflection

• This query will list all LSQOs

Password Generator

Fuzzy string match

Loop to LINQ

1. Get the condition out2. Make a lambda out of it3. Find the nature of your loop4. Use the appropriate operator

How can I do it ? Get it done? Use Re-sharper

Loop => LINQ example

List<int> evenNumbers = new List<int>();

for(int k = 0; k < 100 ; k ++) if (k % 2 == 0) evenNumbers.Add(k);

evenNumbers.AddRange ( Enumerable.Range(0,100) .Where( k => k % 2 == 0) );

Loop

LINQ

This loop is a filter loop

Thank You! Thanks a lot!

Questions ? sudipta.mukherjee@hp.com

top related