티스토리 뷰

Programming/Language

스칼라(scala) - List

글그리 2017. 9. 10. 18:19

List


scala에서 지원하는 collection중 하나로 연결 리스트를 생성하고 관리할 수 있다.






List 생성


scala는 List를 생성하는 여러 방법을 제공한다.

일반적으로 List를 생성하는 코드는 다음과 같다.


val numbers = List(1, 2, 3, 4, 5)


다음은 scala에서 정의한 ::연산자를 이용해 List를 생성하는 코드이다.


val numbers = 1 :: 2 :: 3 :: 4 :: 5 :: Nil


scala 문법이 그냥 이렇게 생겼다고 이해해도 되지만 왜 저런 생성이 가능한지 알아보자.


Nil

아무것도 들어있지 않은 empty List를 재정의한 표현이다. scala의 List는 마지막에 이 Nil을 넣어줘야 그 List가 거기까지 라고 인식한다.


연산자 ::

c++의 연산자 오버로딩과 같이 scala.List 클래스가 ::연산자를 오버로딩 한 것이다. 특이한 점은 위 연산은 오른쪽 항 :: 연산자를 사용해서 왼쪽 항을 연산한다는 점이다. 따라서 :: 연산자를 읽을 때는 오른쪽 항부터 읽어야 한다.

scala.List 클래스에 :: 연산자를 오른쪽 항(LIst)의 앞에 왼쪽 항(List)를 붙인 List를 반환하도록 구현되어 있다.

위 코드를 예로 들면 먼저 Nil이 :: 연산자로 4를 연산하여 결과값인 List(4, Nil)을 반환한다.

// Nil은 List의 마지막을 구분하기 위해 사용되는 것이므로 실제로는 List(4)가 반환된다고 보면 된다.

반환된 List(4)는 또다시 :: 연산자로 3을 연산하여 List(3, 4)를 반환하고, 1까지 반복한 결과는 List(1, 2, 3, 4)가 된다.






List 함수


사용자가 List를 변형시키고 관리할 수 있도록 scala.List 클래스에 여러 함수들이 정의되어있다. 정말 많은 기능이 구현되어 있어서 이 함수들을 모두 숙지할 경우 코드를 굉장히 빠르고 간결하게 작성할 수 있겠지만 그만큼 공부해야 할 시간이 늘어나는 것이므로 장단점이 존재한다.

자주 사용할 수 있는 함수들에 대해 사용법을 알아보자.



foreach

List 내의 모든 개별 원소를 매개변수로 넘겨준 함수로 호출한다. 반환값은 Unit으로 없다. 어떤 함수가 일정한 순서를 가진 데이터로 연속적으로 호출되어야 한다면 연속적인 데이터를 LIst로 저장하고 foreach로 해당 함수를 호출하면 쉽고 간결한 코드를 작성할 수 있다.


List내의 원소를 출력

val numbers = List(1, 2, 3, 4, 5)

numbers.foreach(println(i: Int))
   // >1
   // >2
   // >3
   // >4
   // >5



map

List 내의 모든 개별 원소를 파라미터로 넘겨준 함수로 mapping한 List를 반환한다.

// mapping은 대응시킨다는 의미로 해당 연산으로 모든 원소를 연산한 결과 List를 만들어낸다.


기존 List보다 모든 원소가 2배로 큰 List 만들기

val numbers = List(1, 2, 3, 4, 5)

val dNumbers = numbers.map((i: Int)=>i*2)
   // dNumbers: List[Int] = List(2, 4, 6, 8, 10)



reduce

List 내의 원소들을 파라미터로 넘겨받은 함수로 연산하여 결과를 반환한다. map이나 foreach와 다른점은 결과가 List가 아니라 List로 연산하여 나온 결과 값이라는 것이다.


List의 원소를 모두 더하기

val numbers = List(1, 2, 3, 4, 5)

val total = numbers.reduce((a: Int, b: Int)=>a+b)
   // total: Int = 15



filter

List에서 파라미터로 넘겨준  조건식에 맞는 요소들만 filtering 한 List를 생성하여 반환한다. 전체 집합 List에서 특정 조건에 일치하는 집합을 추려내고 싶을 경우 사용할 수 있다.


50보다 작은 원소들로 추려내기

val numbers = List(85, 46, 77, 105, 31)

val lowNumbers = numbers.filter(_<50)
   // lowNumbers: List[Int] = List(46, 31)


위처럼 간단한 조건식 대신 복잡한 조건을 적용하고 싶다면 Boolean을 반환하는 함수를 파라미터로 넘겨주는 것도 가능하다.



partition

List를 조건에 맞는 List와 맞지 않는 List로 분할한 List들을 가지고 있는 List를 반환한다. 설명이 복잡해 보이지만 예제를 보면 무슨 말인지 알 수 있다.


3의 약수인 원소들만 모은 List와 아닌 List를 가진 List를 반환

val numbers = List(1, 15, 23, 7, 9)

val pNumbers = numbers.partition(_%3==0)
   // pNumbers: (List[Int], List[Int]) = (List(15, 9), List(1, 23, 7))



sortBy

List의 원소들을 정렬하는 함수도 지원한다. 파라미터로 넘겨준 함수 결과값을 가지고 정렬하는 것이기 때문에 넘겨주는 함수를 적절히 변형시키면 여러가지 정렬이 가능하다.


원본을 가지고 정렬. 기본적으로 오름차순 정렬이 된다.

val numbers = List(1, 15, 23, 7, 9)

val pNumbers = numbers.sortBy((i: Int) = i)
   // pNumbers: List[Int] = List(1, 15, 23, 7, 9)


내림차순 정렬을 하기 위해 모든 원소에 -1을 곱하는 함수를 넘겨준다.

val numbers = List(1, 15, 23, 7, 9)

val pNumbers = numbers.sortBy((i: Int) = i * -1)
   // pNumbers: List[Int] = List(23, 15, 9, 7, 1)






마치며


이외에도 수많은 List 함수들이 존재하지만 전부 설명할 수는 없을 것 같다. scala library를 찾아보면 알 수 있겠지만 scala는 어디에 써먹어야될지도 모를 이런 함수들을 잔뜩 준비해놓고 있다. scala를 공부하기 위해 이 함수들을 모두 외우기 보다는,

“꽤 높은 수준의 연산까지 처리해주는 함수를 지원해 주는구나” 라는 생각을 가지고 넘어가도록 하자.

나중에 List로 어떤 연산을 해야 할 때 그 연산이 일반적인 것이라면 라이브러리를 참고하여 해당 기능을 지원하는 함수를 찾아서 코딩하는 것이 좋을 것 같다.



'Programming > Language' 카테고리의 다른 글

C# Tutorial | 기본 문법  (0) 2018.10.29
Python Tutorial | 기본 문법  (0) 2018.09.17
스칼라(scala) - 패턴 매칭(match)  (0) 2017.09.13
스칼라(scala) - 함수  (0) 2017.09.12
스칼라(scala) - 변수(var) 또는 값(val)  (0) 2017.09.11
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함