[C#] LINQ
2021. 9. 13. 19:36
[TOC]
LINQ
- '컬렉션'을 편리하게 다루기 위한 목적으로 만들어진 질의(query) 언어
기본 문법
- From : 어떤 데이터 집합에서 찾나 (from <범위변수> in <데이터원본>)
- Where : 어떤 값의 데이터를 찾을 것인가
- Select : 어떤 항목을 추출할 것인가
namespace LINQ
{
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
where n % 2 == 0
orderby n descending // default는 ascending
select n;
foreach (int num in result)
{
Console.WriteLine($" 짝수 : {num}");
}
}
}
Result
짝수 : 2
짝수 : 4
짝수 : 6
짝수 : 8
짝수 : 10
- result의 타입을 getType으로 확인해보면 System.Linq.OrderedEnumerable`2[System.Int32,System.Int32] 라고 나온다.
IOrderedEnumerable<int> result
- 이런 경우에는 타입을 다음과 같이 지정해주면 var을 사용하지 않아도 된다.
class 사용
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
};
foreach (var profile in profiles)
{
Console.WriteLine($"{profile.Name}, {profile.InchHeight}");
}
}
}
}
class 멤버변수가 배열인 경우
namespace LINQ2
{
class Class
{
public string Name { get; set; }
public int[] Score { get; set; }
}
class MainApp
{
static void Main(string[] args)
{
Class[] arrClass =
{
new Class() { Name = "연두반", Score = new int[] { 99, 80, 70, 24} },
new Class() { Name = "분홍반", Score = new int[] { 60, 45, 87, 72} },
new Class() { Name = "파랑반", Score = new int[] { 92, 30, 85, 94} },
new Class() { Name = "노랑반", Score = new int[] { 90, 88, 0, 17} }
};
var classes = from c in arrClass // 첫번째 데이터 원본
from s in c.Score // 두번째 데이터 원본
where s < 60
orderby s
select new { c.Name, Lowest = s };
foreach (var c in classes)
{
Console.WriteLine($"낙제 : {c.Name} ({c.Lowest})");
}
}
}
}
result
낙제 : 노랑반 (0)
낙제 : 노랑반 (17)
낙제 : 연두반 (24)
낙제 : 파랑반 (30)
낙제 : 분홍반 (45)
group by
- group A by B into c
- A에는 from 절에서 뽑아낸 범위 변수를
- B는 분류 기준
- c는 그룹변수 명 지정
namespace LINQ
{
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)
{
Console.WriteLine($"- 175 미만 / : {Group.GroupKey}");
foreach (var profile in Group.Profiles)
{
Console.WriteLine($" {profile.Name} : {profile.Height}");
}
}
}
}
}
result
- 175 미만 / : True
김태희 : 158
하하 : 171
고현정 : 172
- 175 미만 / : False
이문세 : 178
정우성 : 186
Join
- 두 데이터 원본을 연결함
내부조인 (inner join)
namespace LINQ3_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 Program
{
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}
};
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
join product in arrProduct on profile.Name equals product.Star
select new
{
Name = profile.Name,
Work = product.Title,
Height = profile.Height
};
Console.WriteLine("---내부 조인 결과---");
foreach (var profile in listProfile)
{
Console.WriteLine($"이름 : {profile.Name}, 작품 : {profile.Work}, 키 : {profile.Height}");
}
}
}
}
---내부 조인 결과---
이름 : 정우성, 작품 : 비트, 키 : 186
이름 : 김태희, 작품 : CF 다수, 키 : 158
이름 : 김태희, 작품 : 아이리스, 키 : 158
이름 : 고현정, 작품 : 모래시계, 키 : 172
이름 : 이문세, 작품 : Solo 예찬, 키 : 178
외부 조인 (outer join)
namespace LINQ3_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 Program
{
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}
};
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
join product in arrProduct on profile.Name equals product.Star into ps
from product in ps.DefaultIfEmpty(new Product() { Title = "없음" })
select new
{
Name = profile.Name,
Work = product.Title,
Height = profile.Height
};
Console.WriteLine();
Console.WriteLine("--- 외부 조인 결과 ---");
foreach (var profile in listProfile)
{
Console.WriteLine($"이름 : {profile.Name}, 작품 : {profile.Work}, 키 : {profile.Height}");
}
}
}
}
--- 외부 조인 결과 ---
이름 : 정우성, 작품 : 비트, 키 : 186
이름 : 김태희, 작품 : CF 다수, 키 : 158
이름 : 김태희, 작품 : 아이리스, 키 : 158
이름 : 고현정, 작품 : 모래시계, 키 : 172
이름 : 이문세, 작품 : Solo 예찬, 키 : 178
이름 : 하하, 작품 : 없음, 키 : 171
연습문제
namespace LINQ_practice
{
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}
};
// Cost 50이상 MaxSpeed 150 이상
var selected = from car in cars
where car.Cost >= 50
where car.MaxSpeed >= 150
orderby car.Cost
select car;
foreach (var car in selected)
{
Console.WriteLine($"가격 : {car.Cost}, 최대속도 : {car.MaxSpeed}");
}
}
}
}
'skill > C#' 카테고리의 다른 글
[C#] multipart/form-data 이미지 파일 전송 예제 (0) | 2021.10.15 |
---|---|
[C#] JSON 데이터 POST 전송시 requestbody mapping이 안되는 문제 (0) | 2021.10.12 |
[C#] HTTP GET / POST 요청 처리 (0) | 2021.10.12 |
[C#] 파일입출력(IO) - 스트림(stream), 직렬화(Serializable) (0) | 2021.09.16 |
[C#] 파일입출력(IO) - File, Directory (0) | 2021.09.16 |