줄리아에서 배열의 원소들이 어떤 리스트에 속하는지 체크하는 법
가이드 1
julia> x = rand('a':'c', 10)
10-element Vector{Char}:
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
위와 같은 배열이 있다고 하자. 예제에서 우리의 목표는 'a'
와 'b'
를 모두 골라내는 것이라고 하자. 상식적으로는 포함기호 $\in$로 브로드캐스트하면 될 것 같지만, 결과는 다음과 같다.
julia> x .∈ ['a', 'b']
ERROR: DimensionMismatch("arrays could not be broadcast to a common size; got a dimension with lengths 10 and 2")
DimensionMismatch
에러가 레이즈되었다. 이는 브로드캐스팅이 배열 x
와 범주 ['a', 'b']
양쪽에 동시에 일어났기 때문에 발생한 에러다. 에러메세지를 해석해보자면 x
의 길이 10과 ['a', 'b']
의 길이 2가 동시에 들어와서 혼란스럽다는 것이다.
julia> x .∈ Ref(['a', 'b'])
10-element BitVector:
1
1
1
0
1
0
0
0
1
1
이럴땐 Ref()
함수를 통해 브로드캐스팅 문제를 해결할 수 있다. 이를 통해 ['a', 'b']
속의 'a'
와 'b'
가 스칼라로 취급되고, 위와 같이 두 개의 캐릭터가 있는 곳만을 찾아낼 수 있었다.
주의사항
julia> y = rand('a':'c', 1, 10)
1×10 Matrix{Char}:
'b' 'a' 'b' 'b' 'a' 'c' 'a' 'b' 'b' 'c'
위와 같이 $1 \times 10$ 행렬인 경우를 생각해보자. 언뜻보면 위 가이드에서 본 경우와 다를 게 없어야 할 것 같지만, .∈
가 전혀 다른 방식으로 사용된다.
julia> y .∈ ['a', 'b']
2×10 BitMatrix:
0 1 0 0 1 0 1 0 0 0
1 0 1 1 0 0 0 1 1 0
보다시피 첫 행은 'a'
의 위치를, 둘째 행은 'b'
의 위치를 나타내주고 있다. 이는 벡터냐 행렬이냐의 차이에서 온 것이다.
julia> y .∈ Ref(['a', 'b'])
1×10 BitMatrix:
1 1 1 1 1 0 1 1 1 0
Ref()
를 사용하는 경우에는 일관된 결과를 얻을 수 있다.
환경
- OS: Windows
- julia: v1.7.0