Created
June 9, 2019 07:04
-
-
Save Youngchangoon/f6cb6632f1949cc74b5e7e6c575ea39a to your computer and use it in GitHub Desktop.
LinqStudy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace LinqStudy | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
//TestOrder(); | |
//TestSet(); | |
//TestFilter(); | |
//TestQuantifier(); | |
//TestProjection(); | |
//TestPartitioning(); | |
//TestJoin(); | |
//TestGrouping(); | |
//TestGeneration(); | |
//TestEquality(); | |
//TestElement(); | |
//TestConverting(); | |
//TestConcat(); | |
TestAggregation(); | |
} | |
static void TestSet() | |
{ | |
var words = new[] { "the", "the", "all", "all" }; | |
var words2 = new[] { "a", "b", "c", "the" }; | |
// Distinct() : 중복값 제거 | |
// seq1.Except(seq2): 첫번째 배열의 요소만 있는 요소를 반환 | |
// Intersect(seq2): 첫번째, 두번째 배열의 교집합 요소를 반환 | |
// Union(seq2): 첫번째, 두번째 배열의 합집합 요소를 반환 | |
Console.WriteLine("----- Distinct -----"); | |
var distinctWords = words.Distinct(); | |
foreach (var word in distinctWords) | |
Console.WriteLine(word); | |
Console.WriteLine("----- Except -----"); | |
var exceptWords = words.Except(words2); | |
foreach (var word in exceptWords) | |
Console.WriteLine(word); | |
Console.WriteLine("----- Intersect -----"); | |
var intersectWords = words.Intersect(words2); | |
foreach (var word in intersectWords) | |
Console.WriteLine(word); | |
Console.WriteLine("----- Union-----"); | |
var unionWords = words.Union(words2); | |
foreach (var word in unionWords) | |
Console.WriteLine(word); | |
} | |
static void TestOrder() | |
{ | |
// OrderBy : 값을 오름차순으로 정렬 | |
// OrderByDescending : 값을 내림차순으로 정렬 | |
// ThenBy : 2차정렬을 오름차순으로 | |
// ThenByDescending: 2차정렬을 내림차순으로 | |
// Reverse: 요소의 순서를 반대로 바꿉니다. | |
string[] words = { "the", "quick", "brown", "fox", "jumps" }; | |
IEnumerable<string> query = from word in words | |
orderby word.Length, word.Substring(0, 1) | |
select word; | |
var filteredList = words | |
.OrderBy(word => word.Length) | |
.ThenBy(word => word.Substring(0, 1)) | |
.Reverse(); | |
foreach (string str in query) | |
Console.WriteLine(str); | |
Console.WriteLine(""); | |
foreach (string str in filteredList) | |
Console.WriteLine(str); | |
} | |
private static void TestFilter() | |
{ | |
// Where: 조건에 부합한 요소만 필터링함 | |
// OfType<Type>: 지정된 형식으로 캐스팅 할 수 있는지 여부에 따라 값을 선택 | |
var words = new[] { "the", "quick", "brown", "fox", "jumps" }; | |
var query = from word in words | |
where word.Length == 3 | |
select word; | |
var filteredList = words | |
.Where(word => word.Length == 3) | |
.OfType<int>(); | |
foreach (var word in query) | |
Console.WriteLine(word); | |
foreach (var word in filteredList) | |
Console.WriteLine(word); | |
} | |
private static void TestQuantifier() | |
{ | |
// All: 모두 조건이 맞아야 true 반환(and) | |
// Any: 하나라도 조건이 맞으면 true 반환(or) | |
// Contains: 지정된 요소가 포함되어 있으면 true 반환 | |
var words = new[] { "the", "quick", "brown", "fox", "jumps" }; | |
var allReturnBool = words | |
.All((arg) => arg.Length == 3); | |
var anyReturnBool = words | |
.Any((arg) => arg.Length == 3); | |
var containReturnBool = words | |
.Contains("fox"); | |
Console.WriteLine(allReturnBool); | |
Console.WriteLine(anyReturnBool); | |
Console.WriteLine(containReturnBool); | |
} | |
private static void TestProjection() | |
{ | |
// 소스 값에서 결과 값을 생성하는 것. | |
// Select: 모든 소스값에 대해 하나의 결과만 생성. -> 소스 값과 동일한 갯수 | |
// SeelctMany: 각 소스 값에서 연결된 하위 컬렉션을 포함하는 하나의 자체 결과를 생성 | |
var words = new List<string>() { "an", "apple", "a", "day" }; | |
var phrases = new List<string>() { "an apple a day", "the quick brown fox" }; | |
// ---------- Select ----------- | |
Console.WriteLine("------------ Select ------------"); | |
var query = from word in words | |
select word.Substring(0, 1); | |
foreach (var word in query) | |
Console.WriteLine(word); | |
var filteredList = words.Select(word => word.Substring(0, 1)); | |
foreach (var word in filteredList) | |
Console.WriteLine(word); | |
// ---------- SelectMany ----------- | |
Console.WriteLine("------------ SelectMany ------------"); | |
query = from phrase in phrases | |
from word in phrase.Split(' ') | |
select word; | |
foreach (var s in query) | |
Console.WriteLine(s); | |
filteredList = phrases.SelectMany(ph => ph.Split(' ')); | |
foreach (var s in filteredList) | |
Console.WriteLine(s); | |
// ----- SeleceMany ect ------- | |
List<Bouquet> bouquets = new List<Bouquet>() { | |
new Bouquet { Flowers = new List<string> { "sunflower", "daisy", "daffodil", "larkspur" }}, | |
new Bouquet{ Flowers = new List<string> { "tulip", "rose", "orchid" }}, | |
new Bouquet{ Flowers = new List<string> { "gladiolis", "lily", "snapdragon", "aster", "protea" }}, | |
new Bouquet{ Flowers = new List<string> { "larkspur", "lilac", "iris", "dahlia" }} | |
}; | |
// *********** Select *********** | |
IEnumerable<List<string>> query1 = bouquets.Select(bq => bq.Flowers); | |
// ********* SelectMany ********* | |
IEnumerable<string> query2 = bouquets.SelectMany(bq => bq.Flowers); | |
Console.WriteLine("Results by using Select():"); | |
// Note the extra foreach loop here. | |
foreach (IEnumerable<String> collection in query1) | |
foreach (string item in collection) | |
Console.WriteLine(item); | |
Console.WriteLine("\nResults by using SelectMany():"); | |
foreach (string item in query2) | |
Console.WriteLine(item); | |
} | |
class Bouquet | |
{ | |
public List<string> Flowers { get; set; } | |
} | |
private static void TestPartitioning() | |
{ | |
// 요소를 지정한 만큼 분할하여 가져온다. | |
// Skip(count): 지정한 위치까지 요소를 건너뛴다. | |
// SkipWhile(Func<T, bool>): 조건을 충족하지 않을때까지 요소를 건너뜀 | |
// Take(count): 지정한 위치까지 요소를 사용한다. | |
// TakeWhile(Func<T, bool>): 조건을 충족하지 않을때까지 요소를 사용함 | |
var words = new List<string>() { "a", "b", "c", "a", "b", "a", "c" }; | |
Console.WriteLine("-------- SKIP --------"); | |
var filteredList = words.Skip(3); | |
foreach (var s in filteredList) | |
Console.WriteLine(s); | |
Console.WriteLine("-------- SKIP WHILE --------"); | |
filteredList = words.SkipWhile(s => s != "c"); | |
foreach (var s in filteredList) | |
Console.WriteLine(s); | |
Console.WriteLine("-------- TAKE --------"); | |
filteredList = words.Take(3); | |
foreach (var s in filteredList) | |
Console.WriteLine(s); | |
Console.WriteLine("-------- TAKE WHILE --------"); | |
filteredList = words.TakeWhile(s => s != "c"); | |
foreach (var s in filteredList) | |
Console.WriteLine(s); | |
Console.WriteLine("-------- SKIP(2) TAKE(3) ---------"); | |
filteredList = words.Skip(2).Take(3); | |
foreach (var s in filteredList) | |
Console.WriteLine(s); | |
} | |
class Profile | |
{ | |
public string name { get; set; } | |
public int age { get; set; } | |
} | |
class Score | |
{ | |
public string name { get; set; } | |
public int english { get; set; } | |
public int math { get; set; } | |
} | |
private static void TestJoin() | |
{ | |
// 아무런 관련 없는 두 시퀀스 사이에 통합될수 있는 유사성이 있을때 둘을 합치는 작업. | |
// 내부조인: 일치하는 조건이 있는 경우에만 데이터를 추출함. | |
// 외부조인: 조건이 일치하지 않더라도 기준 데이터를 누락하지 않고 빈 데이터를 채워서 통합 | |
// 참고링크: https://mrw0119.tistory.com/25 | |
var profileList = new List<Profile>() | |
{ | |
new Profile() { name = "수지", age = 11}, | |
new Profile() { name = "아라", age = 22}, | |
new Profile() { name = "민희", age = 33}, | |
}; | |
var scoreList = new List<Score>() | |
{ | |
new Score() { name = "수지", english = 98, math = 66}, | |
new Score() { name = "아라", english = 88, math = 55}, | |
new Score() { name = "현아", english = 77, math = 44}, | |
}; | |
// ----------- 내부조인 ----------- ( Join ) | |
var query = from profile in profileList | |
join score in scoreList on profile.name equals score.name | |
select new | |
{ | |
Name = profile.name, | |
Age = profile.age, | |
Math = score.math, | |
English = score.english, | |
}; | |
Console.WriteLine("------- 내부조인 --------"); | |
foreach (var q in query) | |
{ | |
Console.WriteLine(q); | |
} | |
// ----------- 외부조인 ----------- ( GroupJoin ) | |
query = from profile in profileList | |
join score in scoreList on profile.name equals score.name into temp | |
from score in temp.DefaultIfEmpty(new Score() { math = 0, english = 0 }) // 시험 안본사람은 0점 | |
select new | |
{ | |
Name = profile.name, | |
Age = profile.age, | |
Math = score.math, | |
English = score.english, | |
}; | |
Console.WriteLine("------- 외부조인 --------"); | |
foreach (var q in query) | |
{ | |
Console.WriteLine(q); | |
} | |
} | |
private static void TestGrouping() | |
{ | |
// 그룹화는 데이터들을 각 그룹에 넣어 그룹의 요소들이 공통 특성을 공유하게 하는 작업이다. | |
// GroupBy() (지연된 실행) | |
// ToLookup() (즉각 실행) | |
var numbers = new List<int>() { 35, 44, 200, 87, 3023, 24, 1245, 234, 564 }; | |
var query = from number in numbers | |
group number by number % 2; | |
foreach(var group in query) | |
{ | |
Console.WriteLine(group.Key == 0 ? "\nEven numbers:" : "\nOdd numbers:"); | |
foreach (var i in group) | |
Console.WriteLine(i); | |
} | |
Console.WriteLine("-----------"); | |
var filteredList = numbers.GroupBy(num => num % 10); | |
foreach (var group in filteredList) | |
{ | |
Console.WriteLine("KEY: " + group.Key); | |
foreach (var i in group) | |
Console.WriteLine(i); | |
} | |
Console.WriteLine("-----------"); | |
var lookUpList = numbers.ToLookup(num => num % 10); | |
foreach (var group in filteredList) | |
{ | |
Console.WriteLine("KEY: " + group.Key); | |
foreach (var i in group) | |
Console.WriteLine(i); | |
} | |
} | |
private static void TestGeneration() | |
{ | |
// | |
var numbers = new List<int>() { 35, 44, 200, 87, 3023, 24, 1245, 234, 564 }; | |
var filteredList = numbers.Where(num => num > 10000).DefaultIfEmpty(-99); | |
//foreach (var num in filteredList) | |
// Console.WriteLine(num); | |
filteredList = Enumerable.Empty<int>(); | |
foreach (var num in filteredList) | |
Console.WriteLine(num); | |
filteredList = Enumerable.Range(0, 10); | |
foreach (var num in filteredList) | |
Console.WriteLine(num); | |
filteredList = Enumerable.Repeat(3, 10); | |
foreach (var num in filteredList) | |
Console.WriteLine(num); | |
} | |
private static void TestEquality() | |
{ | |
var numbers_A = new List<int>() { 1, 2, 3, 4, 5 }; | |
var numbers_B = new List<int>() { 1, 2, 3, 4, 5 }; | |
var numbers_C = new List<int>() { 5, 2, 3, 4, 1 }; | |
Console.WriteLine("SequenceEqual(A, B): " + numbers_A.SequenceEqual(numbers_B)); | |
Console.WriteLine("SequenceEqual(A, C): " + numbers_A.SequenceEqual(numbers_C)); | |
} | |
private static void TestElement() | |
{ | |
var numbers = new List<int>() { 35, 44, 200, 87, 3023, 24, 1245, 234, 564 }; | |
Console.WriteLine("ElementAt(1): " + numbers.ElementAt(1)); | |
Console.WriteLine("ElementAtOrDefault(-99): " + numbers.ElementAtOrDefault(-99)); | |
Console.WriteLine("First(n > 100): " + numbers.First(n => n > 100)); | |
Console.WriteLine("FirstOrDefault(n > 10000): " + numbers.FirstOrDefault(n => n > 10000)); | |
Console.WriteLine("Last(n > 1000): " + numbers.Last(n => n > 1000)); | |
Console.WriteLine("Last(n > 10000): " + numbers.LastOrDefault(n => n > 10000)); | |
Console.WriteLine("Single(n == 200): " + numbers.Single(n => n == 200)); | |
Console.WriteLine("Single(n == 2000): " + numbers.SingleOrDefault(n => n == 2000)); | |
} | |
private static void TestConverting() | |
{ | |
var numbers = new List<int>() { 35, 44, 200, 87, 3023, 24, 1245, 234, 564 }; | |
var numbers_obj = new List<object>() { 35, 44, 200, 87, 3023, 24, 1245, 234, 564 }; | |
var enumerable = numbers.AsEnumerable(); | |
var querable = numbers.AsQueryable(); | |
var cast = numbers_obj.Cast<int>(); | |
var ofType = numbers.OfType<float>(); | |
var toArray = numbers.ToArray(); | |
var toDic = numbers.ToDictionary(k => k + 10); | |
var toList = numbers.ToList(); | |
var toLookUp = numbers.ToLookup(k => k + 10, v => v); | |
foreach (var e in toDic) | |
Console.WriteLine("key: " + e.Key + ", val: " + e.Value); | |
foreach (var e in toLookUp) | |
Console.WriteLine("key: " + e.Key); | |
} | |
private static void TestConcat() | |
{ | |
var numbers_A = new List<int>() { 1, 2, 3, 4, 5 }; | |
var numbers_B = new List<int>() { 6, 7, 8, 9, 10 }; | |
var filteredList = numbers_A.Concat(numbers_B); | |
foreach (var num in filteredList) | |
Console.WriteLine(num); | |
} | |
private static void TestAggregation() | |
{ | |
var numbers= new List<int>() { 1, 2, 3, 4, 5 }; | |
Console.WriteLine("Aggreagte(Sum): " + numbers.Aggregate((result, item) => result + item)); | |
Console.WriteLine("Average: " + numbers.Average()); | |
Console.WriteLine("Count: " + numbers.Count()); | |
Console.WriteLine("LongCount(n => n > 3): " + numbers.LongCount(n => n > 3)); | |
Console.WriteLine("Max: " + numbers.Max()); | |
Console.WriteLine("Min: " + numbers.Min()); | |
Console.WriteLine("Sum: " + numbers.Sum()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment