Computer >> 컴퓨터 >  >> 프로그래밍 >> Ruby

Ruby any?, all?, none?, one? 메서드 완벽 정리

오늘은 배열, 해시 또는 Enumerable 모듈을 포함하는 모든 객체에 대해 조건문을 검사할 때 유용하게 쓰이는 4가지 Enumerable 메서드를 알아보겠습니다.

Ruby any?, all?, none?, one? 메서드 완벽 정리

이 4가지 메서드는 모두 true 또는 false를 반환합니다.

Ruby all? 메서드

배열 안의 모든 문자열이 특정 길이를 갖고 있는지 확인하고 싶다고 가정해 봅시다.

전통적인 방식

def all_words_have_specific_size?(words)
  return false if words.empty?

  words.each do |str|
    return false unless str.size == 5
  end

  true
end

words = ["bacon", "orange", "apple"]

all_words_have_specific_size?(words)
# false

위 코드는 문자열을 하나씩 검사하면서, 길이가 조건과 다르면 false를 반환하고 끝까지 통과하면 true를 반환합니다.

단순한 확인 작업인데도 코드가 꽤 깁니다. 이런 검사를 할 때마다 매번 이렇게 작성해야 한다면 상당히 번거로울 것입니다.

사실 우리가 실제로 관심 있는 부분은 딱 한 줄입니다.

str.size == 5

바로 검사하려는 조건 자체죠. 더 좋은 방법이 있을까요?

all? 메서드 활용하기

네, 있습니다! all? 메서드를 사용하면 복잡한 반복 로직을 직접 작성하지 않아도 됩니다.

strings.all? { |str| str.size == 5 }

이게 전부입니다. 코드가 훨씬 간결하고 의도도 명확해집니다.

all?과 빈 배열

반드시 알아두어야 할 중요한 특징이 하나 있습니다.

all? 메서드를 빈 배열에 호출하면 true가 반환됩니다.

예시:

[].all? { |s| s.size == 1 }
# true

설명: false인 요소가 하나도 없기 때문에, 논리적으로 '모든 요소가 참'이라고 판단되는 것입니다. 이는 수학의 공집합에 대한 보편 명제와 같은 원리입니다.

Ruby none? 메서드

all?의 반대 동작이 필요하다면 none?을 사용하세요.

예시:

strings.none? { |str| str.size == 5 }

조건에 맞는 문자열이 하나도 없으면 true, 하나라도 있으면 false를 반환합니다.

마치 if 문에서 unless를 쓰는 것과 비슷한 역할이라고 생각하면 이해하기 쉽습니다.

Ruby any? 메서드

요소 중 하나라도 조건에 맞는지 확인하고 싶다면 어떻게 해야 할까요? 바로 any? 메서드를 사용하면 됩니다!

예시:

[1,2,3,4,5].any?
# true

이 예제에서 any?는 마치 empty?의 반대처럼 동작합니다. 하지만 모든 상황에서 그렇지는 않습니다.

왜냐하면 any?는 다음 질문에 답하기 때문입니다:

"이 배열 안에 truthy(참으로 평가되는) 값이 하나라도 있는가?"

배열에 truthy하지 않은 값(nil/false)만 들어 있다면 배열이 실제로 비어 있지 않더라도 false가 반환됩니다.

예시:

[nil].any?
# false

물론 블록을 함께 전달할 수도 있습니다.

[1,2,3].any? { |n| n > 0 }
# true

이 코드는 최소한 하나의 요소에 대해 n > 0true인지 검사합니다.

Ruby one? 메서드

one? 메서드를 사용하면 정확히 하나의 요소만 조건을 만족하는지 확인할 수 있습니다.

예시:

["a", 1, {}].one? { |obj| obj.kind_of?(Hash) }
# true

블록 없이 사용하면, 배열에 truthy 값(false/nil이 아닌 값)이 정확히 하나만 있는지 검사합니다.

["a"].one?
# true

[].one?
# false

[nil].one?
# false

개인적으로는 size == 1 방식을 선호합니다. one? 메서드는 그렇게 흔하게 사용되지 않기 때문에, 익숙하지 않은 개발자도 size == 1이라면 누구나 즉시 이해할 수 있어 더 명시적이기 때문입니다.

Ruby 2.5의 새로운 기능

Ruby 2.5부터는 이 4가지 메서드(any? / all? / none? / one?)에 grep처럼 인수를 전달할 수 있게 되었습니다.

예시:

[:orange, :apple, :coconut].any?(Symbol)
# true

[1,2,3].all?(1..10)
# true

클래스, 정규표현식, 범위(range) 등을 검사할 때 아주 편리한 단축 기능입니다.

마무리

지금까지 개발 시간을 크게 절약해 줄 수 있는 4가지 강력한 Ruby 메서드를 살펴봤습니다. 이 메서드들은 모두 true 또는 false만 반환한다는 점도 기억하세요.

아직 이 메서드들을 사용해 보지 않으셨다면, 지금 바로 코드에 적용해 보는 건 어떨까요?