배열

배열 에서 jq

5개의 연습 문제

배열 소개

JSON은 배열을 이렇게 정의해요:

배열은 순서가 있는 값들의 모음이에요. 배열은 왼쪽 대괄호 [로 시작하고 오른쪽 대괄호 ]로 끝나요. 값들은 쉼표 ,로 구분해요.

배열은 _어떤 종류_의 JSON 값이든 0개 이상 담을 수 있어요. 배열의 원소가 모두 같은 타입일 필요는 없어요.

배열 만들기

대괄호를 사용해서 원소들을 배열로 모아요.

[1, 2, 3]

_스트림_의 원소들은 대괄호로 감싸서 배열로 담을 수 있어요.

range(5)     # => a stream of 5 numbers
[range(5)]   # => the array [0, 1, 2, 3, 4]

크기

length 함수는 배열에 있는 원소의 개수를 반환해요.

인덱싱과 슬라이싱

배열의 인덱스는 0부터 시작해요.

대괄호 표현식으로 배열에서 원소를 꺼내요: .[2]는 세 번째 원소를 가져와요.

음수 인덱스는 배열의 끝에서부터 거꾸로 세요: .[-1]은 마지막 원소를 가져오고, .[-2]는 끝에서 두 번째예요.

슬라이스는 배열의 부분 수열이에요. .[10:15]는 인덱스 10부터 시작해서 5개의 원소를 반환해요. 끝 인덱스는 포함되지 않아요.

편의를 위한 함수들도 있어요:

  • first는 첫 번째 원소를 가져와요.
  • last는 마지막 원소를 가져와요.
  • nth(n)은 인덱스 n에 있는 원소를 가져와요.

원소의 스트림으로 변환하기

배열의 원소들을 하나씩 스트림으로 만들고 싶을 때가 있어요. 이럴 때는 .[]를 사용해요.

배열에 있는 문자열들의 길이를 스트림으로 얻고 싶다고 해봐요.

["a", "be", "cat", "door"] | length        # => 4 -- the number of elements in the array
["a", "be", "cat", "door"] | .[] | length  # => 1, 2, 3, 4 -- the lengths of each element

빈 대괄호는 파이프를 생략하고 앞의 표현식 바로 옆에 붙일 수 있어요.

["a", "be", "cat", "door"][] | length      # => 1, 2, 3, 4 -- the lengths of each element
# ........................^^

연결과 빼기

+를 사용해서 배열을 연결해요.

[1, 2, 3] + [4, 5]          # => [1, 2, 3, 4, 5]

- 연산자는 오른쪽 배열에 있는 원소들을 왼쪽 배열에서 제거해요.

[range(10)] - [2, 4, 6]     # => [0, 1, 3, 5, 7, 8, 9]

반복하기

jq는 흔히 쓰이는 반복 기능을 위한 여러 함수를 제공해요:

  • map(expr)은 expr을 각 원소에 차례대로 적용한 새 배열을 반환해요.

    [1, 2, 3] | map(. * 10)    # => [10, 20, 30]
    
    
  • select(expr)는 expr을 _하나의 값_에 적용하는 함수예요. 표현식의 결과가 참이면 그 값을 반환하고, 거짓이면 아무것도 반환하지 않아요. null이 아니라 정말로 아무것도요.

    이걸 배열에 적용하려면 map과 함께 사용해요.

    [range(10)] | map(select(. % 2 == 0))    # => [0, 2, 4, 6, 8]
    

    또는 select를 _스트림_에 적용해서 결과를 모을 수도 있어요.

    [range(10) | select(. % 2 == 0)]    # => [0, 2, 4, 6, 8]
    
  • any(condition)와 all(condition)은 배열의 원소 중 조건을 통과하는 게 하나라도 있는지, 또는 모두 통과하는지를 불리언 값으로 반환해요.

    [1, 2, 3, 4] | any(. > 4)    # false
    [1, 2, 3, 4] | any(. >= 4)   # true
    
    [1, 2, 3, 4] | all(. >= 4)   # false
    [1, 2, 3, 4] | all(. <= 4)   # true
    

포함 여부 확인

index로 배열이 어떤 원소를 포함하는지 확인할 수 있어요. 이 함수는 주어진 원소가 배열에 있으면 그 인덱스를 반환하고, 없으면 null을 반환해요.

["carrots", "beef", "potatoes"] | index("beef")    # => 1
["carrots", "beef", "potatoes"] | index("bees")    # => null

IN이라는 반대 역할을 하는 함수도 있어요 (네, 대문자예요). IN의 까다로운 점은 인자가 배열이 아니라 _스트림_이라는 거예요.

"beef" | IN(["carrots", "beef", "potatoes"][])    # => true
"bees" | IN(["carrots", "beef", "potatoes"][])    # => false

그 밖의 함수 (자세한 내용은 설명서를 참고해요)

  • Ruby에는 원소 값을 그 인덱스와 짝지어 주는 편리한 each_with_index 메서드가 있어요. Python에는 enumerate가 있죠. jq에도 비슷한 게 있는데, 이름은 to_entries예요. 이 함수는 배열을 {key: index, value: value} 객체의 배열로 변환해요.

    [11, 22, 33, 44] | to_entries
    # => [{key: 0, value: 11}, {key: 1, value: 22}, {key: 2, value: 33}, {key: 3, value: 44}]
    
  • sort와 sort_by

  • group_by

  • min, max, min_by, max_by

  • unique, unique_by

  • flatten

GitHub에서 편집 링크가 새 창이나 탭에서 열려요

배열 배우기

연습이 잠겨 있어요

배열 개념을 연습하려면 연습 문제 8개를 더 잠금 해제해요