Machineboy空

LINQ 본문

언어/C#

LINQ

안녕도라 2025. 1. 23. 16:29

풀이에 LINQ가 너무 많이 나와서 한 번은 제대로 공부하고 지나가야겠다.

LINQ에 익숙해지면 마치 간단한 영어 문장을 만들 듯 데이터 질의 코드를 작성할 수 있다.


LINQ란?

Language INtegrated Query

컬렉션을 편리하게 다루기 위한 목적으로 만들어진 Query.

 

* 쿼리(Query): 데이터 베이스 등에 정보를 요청하는 것

 

간단하게 말하면, 데이터를 찾아내는 작업을 간편하게 해주는 것


LINQ의 기본 내용

  • From: 어떤 데이터 집합에서 찾을 것인가?
  • Where: 어떤 값의 데이터를 찾을 것인가?
  • Select: 어떤 항목을 추출할 것인가?

예시

그룹 내에서 175cm 미만인 사람을 추출하여라.

  • 전수 검사하며, 조건식으로 height < 17인 객체만 새로운 리스트에 넣는다.
var profiles = from profile in arrProfile	// arrProfile 안에 있는 각 데이터로부터
				where profile.Height < 175	// Height가 175미만인 객체를 골라
                orderby profile.Height		// 키순으로 정렬하여
                select profile;				// profile 객체를 추출한다.

 

훨씬 간결해짐을 볼 수 있다.


LINQ의 기본

  • from <범위 변수> in <데이터 원본>
  • where : 필터 역할, 조건에 부합하는 데이터만 걸러낸다.
  • orderby + ascending / descending
  • select

from 절에서 데이터 원본으로부터 범위 변수를 뽑아내고

where절에서 이 범위 변수의 조건을 검사한후,

그 결과를 orderby절에서 정렬하고

select문을 이용하여 최종 결과를 추출해내는 것이다.

 

using System;
using System.Collections.Generic;
using System.Linq;
					
public class Program
{
	class Profile
	{
		public string Name {get; set;}
		public int Height {get; set;}
	}
	
	public static void Main()
	{
		Profile[] arrProfile =
		{
			new Profile(){Name = "a", Height = 186},
			new Profile(){Name = "b", Height = 158},
			new Profile(){Name = "c", Height = 172}
		};
		
        // from: arrProfile의 profile 중에서
		var profiles = from profile in arrProfile
        
        // where: 조건을 만족하는 것
						where profile.Height < 175
        // orderby: 정렬하여
						orderby profile.Height
        // select: 최종결과를 추출한다.
						select new
						{
							Name = profile.Name,
							InchHeight = profile.Height * 0.393
						};
		
		foreach (var profile in profiles)
			Console.WriteLine($"{profile.Name}, {profile.InchHeight}");
	}
}

using System;
using System.Collections.Generic;
using System.Linq;
					
public class Program
{
	class Car
	{
		public int Cost {get; set;}
		public int MaxSpeed {get; set;}
	}
	
	public static void Main()
	{
		Car[] cars = new Car[]
		{
			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 = from car in cars
						where car.Cost >= 50 && car.MaxSpeed >= 150
						orderby car.Cost
						select new
		{
			Cost = car.Cost,
			MaxSpeed = car.MaxSpeed
		};
		
		foreach (var car in cars)
			Console.WriteLine($"{car.Cost},{car.MaxSpeed}");
	}
}

예제 : 배수의 합 구하기

input 1  7,13,17
input 2 20
output 51

 

7, 13, 17의 배수 중 20보다 작은 수들의 합

7 + 13 + 14 + 17 = 51

using System;
using System.Collections.Generic;
using System.Linq;

public static class SumOfMultiples
{
    public static int Sum(IEnumerable<int> multiples, int max)
    {
        return Enumerable.Range(1, max - 1)
        	// 하나라도 참이면 참. 즉, multiple 요소로 하나라도 나눠지면 필터링
            .Where(n => multiples.Any(m => m != 0 && n % m == 0))  
            .Sum(); 
    }
}

 


Enumerable.Where

조건자에 따라 값의 시퀀스를 필터링한다.

반환형 IEnumerable<T>

 

List<string> fruits = new List<string>{"apple", "banana", "mango", "strawberry"};

IEnumerable<string> query = fruits.Where(fruit => fruit.Length < 6);
// return : apple, mango

Enumerable.Any

시퀀스에  요소가 하나라도 있는지 또는 특정 조건에 맞는 요소가 있는지 확인

반환형 True, False
class Pet
{
	public string Name {get; set;}
    public int Age {get; set;}
    public bool Vaccinated {get; set}
}

public static void AnySample()
{
	Pet[] pets =
    	{
        	new Pet{Name = "A", Age = 8, Vaccinated = true},
            new Pet{Name = "B", Age = 3, Vaccinated = false},
            new Pet{Name = "C", Age = 5, Vaccinated = false}
        };
    
    bool unvaccinated = pets.Any(p => p.Age > 1 && p.Vaccinated == false);
    // return : true
}

Enumerable.Count

시퀀스 요소의 수를 반환

반환형 Int32

 

string[] fruits = {"apple", "banana", "mango"};

int numberOfFruits = fruits.Count();
// return : 3

Enumerable.Sum

숫자 값 시퀀스의 합을 계산

반환 Single
List<float> numbers = new List<float> { 43.68F, 1.25F, 583.7F, 6.5F };

float sum = numbers.Sum();
// return :  635.13

Enumerable.FirstOrDefault

시퀀스의 첫 번째 요소를 반환하거나 요소가 없으면 기본값을 반환

반환형 IEnumerable<T>
string[] names = { "Hartono, Tommy", "Adams, Terry",
                     "Andersen, Henriette Thaulow",
                     "Hedlund, Magnus", "Ito, Shu" };

string firstLongName = names.FirstOrDefault(name => name.Length > 20);
// return : Andersen, Henriette Thaulow

Enumberable.Contains

같음 비교자를 사용하여 시퀀스에 지정 요소가 들어있는지 확인

반환형 True, False
string[] fruits = { "apple", "banana", "mango", "orange", "passionfruit", "grape" };

bool hasMango = fruits.Contains("mango");
// return : true