IEnumerable<T>
의 파생 형식(배열, 컬렉션 객체)이어야 한다.예제
using System;
using System.Linq;
namespace From
{
class MainApp
{
static void Main(string[] args)
{
int[] numbers = { 9, 2, 6, 4, 5, 3, 7, 8, 1, 10 };
var result = from n in numbers // from 범위변수 in 데이터원본
where n % 2 == 0
orderby n
select n;
foreach (int n in result)
Console.WriteLine($"짝수 : {n}");
}
}
}
예제
// 원본 데이터
Profile[] arrProfile = {
new Profile(){Name="정우성", Height=186},
new Profile(){Name="김태희", Height=158},
new Profile(){Name="고현정", Height=172},
new Profile(){Name="이문세", Height=178},
new Profile(){Name="하동훈", Height=171}
};
// where
var profiles = from profile in arrProfile
where profile.Height < 175 // Height 175 미만 필터링
select profile;
예제
// orderby
var profiles = from profile in arrProfile
where profile.Height < 175
orderby profile.Height // Height를 기준으로 정렬 (기본 : 오름차순)
select profile;
// ascending 키워드
var profiles = from profile in arrProfile
where profile.Height < 175
orderby profile.Height ascending
select profile;
// descending 키워드
var profiles = from profile in arrProfile
where profile.Height < 175
orderby profile.Height descending
select profile;
IEnumerable<T>
로 반환되는데,T
는 select
문에 의해 결정된다.예제
var profiles = from profile in arrProfile
where profile.Height < 175
orderby profile.Height
select profile; // IEnumerable<Profile> : Height가 175 미만인 Profile 객체
var profiles = from profile in arrProfile
where profile.Height < 175
orderby profile.Height
select profile.Name; // IEnumerable<string> : Height가 175 미만인 Name 프로퍼티
var profiles = from profile in arrProfile
where profile.Height < 175
orderby profile.Height
select new{ Name = profile. Name, InchHeight = profile.Height * 0.393 }; // 무명 형식
using System;
using System.Collections.Generic;
using System.Linq;
namespace SimpleLinq
{
class Profile
{
public string Name { get; set; }
public int Height { get; set; }
}
class MainApp
{
static void Main(string[] args)
{
Profile[] arrProfile =
{
new Profile(){Name="정우성", Height=186},
new Profile(){Name="김태희", Height=158},
new Profile(){Name="고현정", Height=172},
new Profile(){Name="이문세", Height=178},
new Profile(){Name="하하", Height=171}
};
var profiles = from profile in arrProfile
where profile.Height < 175
orderby profile.Height
select new
{
Name = profile.Name,
InchHeight = profile.Height * 0.393
};
Console.WriteLine(profiles);
Console.WriteLine();
foreach (var profile in profiles)
Console.WriteLine($"{profile.Name}, {profile.InchHeight}");
}
}
}
group A by B into C
예제
using System;
using System.Linq;
namespace GroupBy
{
class Profile
{
public string Name { get; set; }
public int Height { get; set; }
}
class MainApp
{
static void Main(string[] args)
{
Profile[] arrProfile =
{
new Profile(){Name="정우성", Height=186},
new Profile(){Name="김태희", Height=158},
new Profile(){Name="고현정", Height=172},
new Profile(){Name="이문세", Height=178},
new Profile(){Name="하하", Height=171}
};
var listProfile = from profile in arrProfile
orderby profile.Height
group profile by profile.Height < 175 into g // 분류/그룹핑
select new { GroupKey = g.Key, Profiles = g };
foreach (var Group in listProfile) // Group은 IGrouping<T> 형식
{
Console.WriteLine($"- 175cm 미만? : {Group.GroupKey}"); // Group.GroupKey -> True/False
foreach (var profile in Group.Profiles)
{
Console.WriteLine($">>> {profile.Name}, {profile.Height}");
}
}
}
}
}
from a in A
join b in B on a.XXXX equals b.YYYY
// on절의 join 조건은 동등만 허용 (작거나 큰 경우 허용X)
join
절을 이용해 조인을 수행 후 그 결과를 임시 컬렉션에 저장DefaultIfEmpty
연산을 통해 임시 컬렉션의 비어 있는 조인 결과에 빈 값 삽입DefaultIfEmpty
연산을 거친 임시 컬렉션에서 다시 from절을 통해 범위 변수 추출예제
using System;
using System.Linq;
namespace Join
{
class Profile
{
public string Name { get; set; }
public int Height { get; set; }
}
class Product
{
public string Title { get; set; }
public string Star { get; set; }
}
class MainApp
{
static void Main(string[] args)
{
// 배우 프로필(A) | Name, Height 필드로 구성 (기준)
Profile[] arrProfile =
{
new Profile(){Name="정우성", Height=186},
new Profile(){Name="김태희", Height=158},
new Profile(){Name="고현정", Height=172},
new Profile(){Name="이문세", Height=178},
new Profile(){Name="하하", Height=171}
};
// 작품 정보(B) | Product, Star 필드로 구성
Product[] arrProduct =
{
new Product(){Title="비트", Star="정우성"},
new Product(){Title="CF 다수", Star="김태희"},
new Product(){Title="아이리스", Star="김태희"},
new Product(){Title="모래시계", Star="고현정"},
new Product(){Title="Solo 예찬", Star="이문세"}
};
// 내부 조인 | 겹치는 것 모두 반환
var listProfile =
from profile in arrProfile // A 요소 추출
join product in arrProduct on profile.Name equals product.Star
// [A의 필드 Name]과 [B의 필드 Star]가 동일한 A&B 요소 join
select new //
{
Name = profile.Name,
Work = product.Title,
Height = profile.Height
};
Console.WriteLine("--- 내부 조인 결과 ---");
foreach (var profile in listProfile)
{
Console.WriteLine("이름:{0}, 작품:{1}, 키:{2}cm",
profile.Name, profile.Work, profile.Height);
}
// 외부 조인 | 기준 데이터와 겹치는 것 모두 반환
listProfile =
from profile in arrProfile // A 요소 추출
join product in arrProduct on profile.Name equals product.Star into ps
// 모든 A의 요소와 [A의 필드 Name]&[B의 필드 Star]가 동일한 B 요소 join => join 결과 임시 컬렉션(ps)에 저장
from sub_product in ps.DefaultIfEmpty(new Product(){Title="그런거 없음"})
// 임시 컬렉션에 DefaultIfEmpty 연산 적용, Title : 빈 곳에 채울 내용
select new
{
Name = profile.Name,
Work = sub_product.Title,
Height = profile.Height
};
Console.WriteLine();
Console.WriteLine("--- 외부 조인 결과 ---");
foreach (var profile in listProfile)
{
Console.WriteLine("이름:{0}, 작품:{1}, 키:{2}cm",
profile.Name, profile.Work, profile.Height);
}
}
}
}
// 쿼리식
var profiles = from profile in arrProfile
where profile.Height < 175
orderby profile.Height).
select new {Name = profile.Name, InchHeight = profile.Height * 0.393};
// C# 컴파일러의 번역
var profiles = arrProfile // 각 메소드에 입력되는 람다식의 매개변수로 변경
.Where(profile => profile.Height < 175) // where -> Where() 메소드
.OrderBy(profile => profile.Height) // orderby -> OrderBy() 메소드
.Select(profile => // select -> Select()
new
{
Name = profile.Name,
InchHeight = profile.Height * 0.393
});
예제
using System;
using System.Linq;
/* Where(), OrderBy(), Select() 메소드는
System.Linq 네임스페이스에 정의되어 있는 IEnumerable<T>의 확장 메소드 */
namespace SimpleLinq2
{
class Profile
{
public string Name { get; set; }
public int Height { get; set; }
}
class MainApp
{
static void Main(string[] args)
{
Profile[] arrProfile =
{
new Profile(){Name="정우성", Height=186},
new Profile(){Name="김태희", Height=158},
new Profile(){Name="고현정", Height=172},
new Profile(){Name="이문세", Height=178},
new Profile(){Name="하하", Height=171}
};
var profiles = arrProfile.
Where(profile => profile.Height < 175).
OrderBy(profile => profile.Height).
Select(profile =>
new
{
Name = profile.Name,
InchHeight = profile.Height * 0.393
});
foreach (var profile in profiles)
Console.WriteLine($"{profile.Name}, {profile.InchHeight}");
}
}
}
C# 지원 LINQ 쿼리 식(11) < LINQ 표준 연산자 수 (53)
LINQ 쿼리 식과 메소드 함께 사용
// Average() 메소드 호출 코드 1
var profiles = from profile in arrProfile
where profile.Height < 180
select profile;
double Average = profiles.Average(profile => profile.Height);
Console.WriteLine(Average);
// Average() 메소드 호출 코드 2
double Average = (from profile in arrProfile
where profile.Height < 180
select profile).Average(profile => profile.Height);
Console.WriteLine(Average);
예제
/* 키 175 기준으로 연예인 프로필 그룹을 나누고
각 그룹의 키가 가장 큰 연예인, 가장 작은 연예인 뽑기 */
using System;
using System.Linq;
namespace MinMaxAvg
{
class Profile
{
public string Name { get; set; }
public int Height { get; set; }
}
class MainApp
{
static void Main(string[] args)
{
Profile[] arrProfile =
{
new Profile(){Name="정우성", Height=186},
new Profile(){Name="김태희", Height=158},
new Profile(){Name="고현정", Height=172},
new Profile(){Name="이문세", Height=178},
new Profile(){Name="하하", Height=171}
};
var heightStat = from profile in arrProfile
group profile by profile.Height < 175 into g
select new
{
Group = g.Key==true?"175미만":"175이상",
Count = g.Count(),
Max = g.Max(profile => profile.Height),
Min = g.Min(profile => profile.Height),
Average = g.Average(profile => profile.Height)
};
foreach (var stat in heightStat)
{
Console.Write("{0} - Count:{1}, Max:{2}, ",
stat.Group, stat.Count, stat.Max);
Console.WriteLine("Min:{0}, Average:{1}",
stat.Min, stat.Average);
}
}
}
}
class Car
{
public int Cost { get; set; }
public int MaxSpeed { get; set; }
}
class Program
{
static void Main(string[] args)
{
Car[] cars =
{
new Car(){Cost = 56, MaxSpeed = 120},
new Car(){Cost = 70, MaxSpeed = 150},
new Car(){Cost = 45, MaxSpeed = 180},
new Car(){Cost = 32, MaxSpeed = 200},
new Car(){Cost = 82, MaxSpeed = 280},
};
// LINQ
var selected = from car in cars
where car.Cost >= 50 && car.MaxSpeed >= 150
select car;
foreach (var s in selected)
Console.WriteLine($"Cost = {s.Cost}, MaxSpeed = {s.MaxSpeed}");
}
}
class Car
{
public int Cost { get; set; }
public int MaxSpeed { get; set; }
}
class Program
{
static void Main(string[] args)
{
Car[] cars =
{
new Car(){Cost = 56, MaxSpeed = 120},
new Car(){Cost = 70, MaxSpeed = 150},
new Car(){Cost = 45, MaxSpeed = 180},
new Car(){Cost = 32, MaxSpeed = 200},
new Car(){Cost = 82, MaxSpeed = 280},
};
// var selected = cars.Where(c => c.Cost < 60).OrderBy(c => c.Cost);
// LINQ
var selected = from car in cars
where car.Cost < 60
orderby car.Cost
select car;
foreach (var s in selected)
Console.WriteLine($"Cost = {s.Cost}, MaxSpeed = {s.MaxSpeed}");
}
}