728x90
ruby의 배열내의 카운트를 세는 법
서론
- 최근 어느 로직을 작성하는데, 배열내의 두개 이상의 값의 갯수를 세어야 하는 케이스가 있었다.
- 각각에 대한 갯수를 세면 쉽지만, 그렇게 되었을 경우 순회를 2번이상 돌아야 하기 때문에 데이터가 많다면 성능상 좋지 않다고 판단하여, 다른 방법이 있을지 찾아보았다.
기본 count
- 기본적으로 아래와 같이 코드가 있다고 해봅시다.
arr = [1,1,1,2,3,3,4,4,4,4,4,4,5,5,5,5,5]
- arr에서 1의 갯수와 5의 갯수를 구하기 위해선 아래와 같이 코드를 작성하게 됩니다.
arr.count(1) # 3
arr.count(5) # 5
- 이렇게 하면 두번의 계산이 있어야 하며, 더 추가되었을때 코드가 계속해서 추가되어 불편함이 있을수 있습니다.
기본 for문을 이용하기
arr = [1,1,1,2,3,3,4,4,4,4,4,4,5,5,5,5,5]
one_count = 0
five_count = 0
arr.each do |number|
one_count += 1 if number == 1
five_count += 1 if number == 5
end
- 위와 같이 for문을 사용해서 손쉽게 할수 있습니다.
- 한번의 순회이지만, 코드가 조금 더 길어진걸 확인할수 있습니다
each_with_object 를 활용해서 해쉬로 만들기
counters = arr.each_with_object({}) { |number, count_hash| count_hash[number] += 1 } # {1=>3, 2=>1, 3=>2, 4=>6, 5=>5}
counters[1] # 3
counters[5] # 5
- each_with_object를 활용해 hash로 만들면 위의 코드가 한줄로 되면서 해쉬가 나오게 되고 다른 갯수들도 차후에 추가될때 손쉽게 사용해볼수 있습니다.
- 이런식으로 작성한다면 간결하고, 한번의 순회 및 계산만으로 처리할수 있는걸 확인할수 있습니다.
- cf) each_with_object는 Ruby의 열거 가능한 객체(Enumerable)에 대한 메소드입니다. 이 메소드는 각 요소에 대해 블록을 실행하며, 그 중간 변경사항을 특정 객체에 누적합니다. 이 메소드는 마지막으로 사용된 객체를 반환합니다. 위의 코드에서 each_with_object는 빈 배열 []을 넘겨받고, 각 배열 요소에 대해 블록을 실행합니다. 블록 안에서는 각 요소를 2배하여 원래의 빈 배열에 추가합니다. 이 경우, 원래의 빈 배열이 변경되면서, 그 변경사항이 누적됩니다. 루프가 끝나면 최종적으로 변경된 객체 (즉, [2,4,6,8])이 반환됩니다. 메소드는 객체를 순회하면서 중간 결과를 누적하거나 이용해야 할 때 유용합니다.
결론
- 단순한 count를 사용하기 보단, 좀더 계산을 덜 할수 있는 방법들을 고민해보면 좋을거 같습니다.
- 아울러 처음엔 count로 구현한뒤 리팩토링 단계에서 이러한 방식들을 고민해봐도 충분하다고 생각합니다.
728x90
728x90
'Backend > Ruby' 카테고리의 다른 글
ruby의 ?(Question Mark / Boolean)의 의미 (0) | 2023.11.25 |
---|---|
ruby의 !(Exclamation mark / Bang)의 의미 (4) | 2023.11.24 |
Numeric의 zero? & positive? & negative? (0) | 2023.01.29 |
Mastering data structures in Ruby — Doubly linked lists(Ruby의 데이터 구조 마스터 하기 - 이중 연결 목록) (0) | 2021.12.25 |
Comparing Each vs Select vs Map vs Collect in Ruby(루비의 Each vs Select vs Map vs Collect 비교) (0) | 2021.12.11 |