개발/유니티

[유니티] LINQ

kimchangmin02 2025. 7. 18. 21:11

1-1

개념

(약간 함수형 언어랑 비슷한데)

여러가지 재료중에,특정한 재료를 찾아야할때
빈 그릇을 두고 재료를 하나씩 확인하며 내가 원하는 것만 '옮겨 담는' 방식입니다. 과정이 길고 번거롭죠.

 

LINQ는, '당근만 통과시키는 마법 체' 원하는 규칙(체)을 말하기만 하면, 데이터가 그 체를 지나가면서 즉시 걸러집니다. 중간에 임시 그릇을 둘 필요 없이, 물 흐르듯이 결과가 만들어지는 거죠.

 

LINQ는 "레고 정리 로봇"이에요! 🤖

상상해 보세요. 여러분 앞에 색깔도, 크기도, 모양도 제멋대로인 레고 블록이 한가득 쌓여있어요. (이 레고 더미가 바로 C#의 리스트, 배열 같은 데이터 덩어리예요.)

여기서 엄마가 미션을 줍니다.
"이 중에서 파란색 블록만 골라내서, 크기가 큰 것부터 순서대로 정리해서 새로운 상자에 담아줘!"

이걸 여러분이 직접 하려면 어떨까요?

  1. 레고를 하나씩 다 손으로 집어본다. (for 반복문)
  2. 이게 파란색인지 아닌지 눈으로 확인한다. (if 조건문)
  3. 파란색이면 옆에 따로 모아둔다.
  4. 다 모았으면, 이제 그 파란색 블록들을 크기 순서대로 다시 정렬한다.
  5. 정렬이 끝나면 새 상자에 담는다.

...생각만 해도 귀찮고 복잡하죠? 😫

이때, "레고 정리 로봇" (이게 바로 LINQ!) 이 있다면 어떨까요?
여러분은 그냥 로봇에게 말로 명령만 하면 돼요.

"헤이 로봇! 저기 레고 더미( scores )에서..."

  1. "파란색인 것만 골라내고 (Where)"
  2. "크기가 큰 순서대로 줄 세운 다음 (OrderByDescending)"
  3. "새 상자에 담아줘! (ToList)"

로봇은 이 명령을 듣고 알아서 모든 귀찮은 일을 순서대로 처리해서, 여러분에게는 딱 원하는 결과물(새 상자)만 가져다줍니다.

결론: LINQ는 데이터(레고 더미)를 다룰 때, 우리가 귀찮게 하나하나 처리하지 않고, "어떤 걸, 어떤 순서로, 어떻게 해줘" 라고 명령만 내리면 알아서 처리해주는 아주 똑똑한 로봇(기능)이에요!


 

 

 

1-2

예제및 설명

 

// var highScores = scores.Where(s => s > 100).OrderByDescending(s => s).ToList();

1. scores
이게 바로 아까 말한 "레고 블록 더미" 예요.
예를 들어, scores 안에는 게임 점수들이 이렇게 들어있다고 상상해 보세요.
[ 10, 120, 50, 150, 99 ]

2. .Where(s => s > 100)

  • . (점): "그리고... 다음 작업은" 이라는 뜻이에요. 명령을 서로 연결해주는 연결고리죠.
  • Where: "조건에 맞는 것만 골라내!" 라는 뜻의 명령이에요. (Where = 어디있는지 찾아봐!)
  • (s => s > 100): 이게 바로 로봇에게 알려주는 "규칙" 이에요. 람다식이죠!
    • s: scores 안에 있는 점수 하나하나를 잠시 s 라고 부를게!
    • =>: 규칙은...
    • s > 100: 그 점수(s)가 100보다 커야 해!

👉 여기까지 실행하면?
로봇은 [ 10, 120, 50, 150, 99 ] 에서 100보다 큰 것만 골라내요.
그럼 로봇의 손에는 [ 120, 150 ] 이 들려있겠죠?

3. .OrderByDescending(s => s)

  • OrderByDescending: "큰 것부터 작은 것 순서로 줄 세워!" 라는 뜻의 명령이에요. (Descending = 내림차순)
  • (s => s): 이건 "정렬 기준" 을 알려주는 규칙이에요.
    • s: 우리가 골라낸 점수(120, 150) 하나하나를 s라고 부를게!
    • =>: 정렬 기준은...
    • s: 그냥 그 점수(s) 자체를 기준으로 해줘!

👉 여기까지 실행하면?
로봇은 손에 들고 있던 [ 120, 150 ] 을 큰 순서대로 줄을 세워요.
그럼 로봇의 손에는 이제 [ 150, 120 ] 이 들려있겠죠?

4. .ToList()

  • ToList: "지금까지 작업한 결과를 진짜 '리스트(새 상자)'로 만들어서 나에게 줘!" 라는 마지막 명령이에요.
  • 이 명령이 있어야, 로봇이 최종 결과물을 진짜 상자에 담아서 우리에게 건네줍니다.

👉 여기까지 실행하면?
로봇은 [ 150, 120 ] 이라는 결과물을 예쁜 새 리스트(상자)에 담아서 우리에게 줍니다.

5. var highScores = ...

  • var highScores: "로봇이 건네준 그 새로운 상자에 highScores 라고 이름표를 붙이자!"
  • 이제 우리는 highScores 라는 이름의 상자(변수)를 열면, [ 150, 120 ] 이라는 멋진 결과물을 볼 수 있게 되는 거죠!

최종 정리

scores.Where(s => s > 100).OrderByDescending(s => s).ToList()

이 코드는 이렇게 읽을 수 있어요.

"점수들(scores) 중에서...
100점을 넘는 것만 골라내고(Where),
그것들을 큰 순서대로 정렬한 다음(OrderByDescending),
새로운 리스트로 만들어줘(ToList)."

어때요? 복잡한 반복문이나 조건문 없이, 우리가 원하는 것을 이야기하듯이 코드를 쓸 수 있게 해주죠? 이게 바로 LINQ의 가장 강력하고 멋진 점이랍니다! 마치 데이터 요리사 같아요! 👨‍🍳

 

 

 

 

 

1-3

모르겟는 부분

 

1-3(1)

Q

원본 데이터는 절대 건드리지 않아요 (불변성)

 

OrderByDescending(s => s).ToList() 이 코드는 scores 정렬하는 게 아니라,
scores 바탕으로 정렬된 '복사본'을 새로 만드는 것이에요.

 

 

1-3(2)

Q함수를 '재료'로 넘긴다는 건 무슨 뜻일까요? (고차 함수)

 

LINQ에 있는 Where OrderByDescending 같은 기능들은 아주 실력 좋은 **'전문 요리사'**라고 생각하세요.

  • Where 요리사: "재료를 골라내는(필터링) 전문가"
  • OrderByDescending 요리사: "재료를 순서대로 정렬하는 전문가"

자, 여러분이 Where 요리사에게 일을 시키려고 해요.
"요리사님, 여기 재료(scores) 좀 골라주세요!"

그러면 Where 요리사가 여러분에게 되물을 거예요.
"네? 어떤 기준으로 골라드릴까요?"

요리사는 '골라내는 기술'은 최고지만, '오늘의 기준'이 뭔지는 몰라요. 그 기준은 여러분이 알려줘야 하죠.
이때 여러분이 요리사에게 건네주는 **쪽지(레시피)**가 바로 람다 표현식 (s => s > 100) 입니다.

  • Where( ): 괄호 ()는 요리사에게 레시피를 건네주는 손이에요.
  • s => s > 100: 쪽지에는 이렇게 쓰여있어요.
    • "재료 하나하나를 s라고 부를 건데요, (s =>)"
    • "그 s가 100보다 큰 것만 남겨주세요! (s > 100)"

Where 요리사는 이 쪽지를 받아들고, 그제서야 "아하! 100보다 큰 것만 고르면 되는구나!" 하고 일을 시작할 수 있는 거죠.

OrderByDescending 요리사도 마찬가지예요.
"요리사님, 이거 정렬해주세요!" 하면,
"네? 무슨 기준으로 정렬할까요? 크기순? 이름순? 색깔순?" 하고 물어볼 거예요.

여기에 여러분이 (s => s) 라는 아주 간단한 레시피를 주는 거예요.

  • "재료 하나하나를 s라고 부를 건데요, (s =>)"
  • "기준은 그냥 그 재료(s) 자체로 해주세요!"

만약 재료가 '학생'들이었고, '나이' 순으로 정렬하고 싶었다면?
students.OrderBy(st => st.Age) 와 같이 '나이를 기준으로 해줘!' 라는 다른 레시피를 건네주면 됩니다.

정리:

  • 고차 함수: Where OrderBy처럼, 스스로 전문가이지만 **'구체적인 규칙(레시피)'을 외부에서 받아야만 일할 수 있는 똑똑한 함수(요리사)**를 말해요.
  • 람다 표현식: 그 요리사에게 건네주는 **간단하고 명확한 '한 줄짜리 레시피'**인 셈이죠.

그래서 "함수를 재료처럼 넘긴다"는 말은, **"요리사(함수)에게 레시피(함수)를 건네준다"**는 뜻이랍니다! 이 덕분에 우리는 똑같은 Where 요리사를 가지고도 '100보다 큰 것', '짝수만', '이름이 김씨인 것' 등 온갖 다양한 규칙을 적용할 수 있게 되는 거예요.

 

 

 

 

 

 

1-3(3)

Q

SQL 쿼리문/자바의 스트림 api가 뭐지

 

1. SQL 쿼리문은 "도서관 사서에게 보내는 쪽지"예요 📜

여러분이 아주 아주 큰 **도서관(데이터베이스)**에 갔다고 상상해 보세요. 책이 수백만 권 있어요.
여기서 여러분이 직접 '해리포터' 책을 찾으려면 하루 종일 걸릴 거예요.

이때, 여러분은 직접 책을 찾지 않고 **도서관 사서(데이터베이스 관리 시스템)**에게 **쪽지(SQL 쿼리문)**를 써서 보내요.

쪽지 내용:

Generated sql

-- "SELECT 제목, 작가"
-- '제목'과 '작가' 정보를 알려주세요.

-- "FROM 책들"
-- '책들'이 있는 서가에서요.

-- "WHERE 작가 = 'J.K. 롤링' AND 출판년도 > 2000"
-- 조건이 있는데요, 작가가 'J.K. 롤링'이어야 하고, 2000년 이후에 나온 책이어야 해요.
 
Use code with caution.SQL

이 쪽지를 사서에게 주면, 사서는 도서관 시스템을 이용해서 정확하게 조건에 맞는 책만 찾아서 여러분에게 가져다줍니다.

SQL 쿼리문(Query = 질문)이란?

  • **데이터베이스(거대한 도서관)**라는 데이터 창고에서,
  • 내가 원하는 데이터(책)가 무엇인지 **정해진 양식에 맞춰 글로 질문(요청)**하는 문장이에요.
  • "이런이런 조건에 맞는 데이터를 골라서(SELECT), 이런 순서로 정렬해서(ORDER BY) 보여주세요" 라고 명령하는 거죠.

LINQ와 비교하면?
LINQ가 "레고 정리 로봇"에게 말로 명령하는 거였다면,
SQL은 "도서관 사서"에게 정해진 양식의 쪽지로 요청하는 거예요.
둘 다 "내가 원하는 데이터를 가져와줘!" 라고 요청하는 점은 똑같죠? 그래서 LINQ를 만들 때 SQL의 편리한 문법을 많이 참고했어요.


2. 자바의 스트림(Stream) API는 "음료수 공장 라인"이에요 🏭

이번엔 음료수 공장을 상상해 보세요.

  1. 샘물(원본 데이터): 공장 옆에 깨끗한 샘물이 잔뜩 있어요. (자바의 리스트, 배열 같은 데이터 덩어리)
  2. 파이프 연결(스트림 생성): 이 샘물을 공장으로 끌어오기 위해 커다란 파이프(Stream)를 연결해요. 이제 샘물이 파이프를 통해 '흐르기(Stream)' 시작해요.
  3. 공장 라인(중간 연산): 파이프를 흐르는 물은 여러 기계를 거쳐요.
    • 필터 기계 (filter): 나뭇잎이나 흙 같은 불순물을 걸러내요. (LINQ의 Where와 같아요!)
    • 과일즙 첨가 기계 (map): 밋밋한 물에 오렌지 맛, 포도 맛을 추가해요. (데이터를 다른 형태로 바꿈)
    • 탄산 주입 기계 ...
    • ... 등등 여러 기계를 쭉 연결해서 통과시켜요.
  4. 병에 담기(최종 연산): 마지막으로, 완성된 음료수를 병에 담아서(collect) 우리에게 제품으로 내놓아요. (LINQ의 ToList와 같아요!)

자바의 스트림(Stream) API란?

  • 데이터 덩어리(샘물)를 직접 건드리지 않고,
  • 데이터가 흐르는 파이프(Stream)를 만들어서,
  • 그 파이프에 여러 가지 처리 기계(필터, 맵 등)를 순서대로 연결한 다음,
  • 최종적으로 결과물을 병에 담아(collect) 완성하는 방식이에요.

LINQ와 비교하면?
개념적으로 거의 똑같아요!

  • 데이터를 직접 다루지 않고 **흐름(파이프라인)**을 만든다는 점.
  • 중간에 여러 처리 단계를 점(.)으로 계속 연결한다는 점.
  • 원본 데이터(샘물)는 그대로 보존된다는 점.

그래서 "자바의 스트림은 C#의 LINQ와 비슷하다" 또는 그 반대로 이야기하는 거랍니다. 목적과 사용 방식이 매우 닮은, 서로 다른 언어에 있는 쌍둥이 같은 기능이라고 생각하면 쉬워요.

최종 요약!

기능 비유 하는 일
SQL 쿼리문 도서관 사서에게 보내는 쪽지 데이터베이스(창고)에 원하는 데이터를 요청하는 글
자바 스트림 API 음료수 공장 라인 데이터(물)의 **흐름(파이프)**을 만들어 여러 단계로 가공
C# LINQ 레고 정리 로봇 데이터(레고)를 어떻게 처리할지 명령해서 새로운 결과물을 얻음

세 가지 모두 "많은 데이터 덩어리에서 내가 원하는 것만, 원하는 방식으로 쉽고 편하게 뽑아내자!" 라는 똑같은 목표를 가지고 태어난 멋진 기술들이랍니다