Ruby inject와 reduce의 기능
inject와 reduce는 Ruby Enumerable 모듈의 핵심 메서드로, 컬렉션 요소를 반복적으로 블록에 적용하여 단일 값으로 “축소”합니다. 초기 “누산기”(memo)를 시작으로 각 요소를 결합하는 방식입니다.
-
시그니처:
enumerable.inject(initial_value) { |memo, element| ... }또는enumerable.inject(:+). -
초기값의 중요성: 초기값 제공 시 해당 값이
memo가 되어 첫 요소부터 반복합니다. 초기값이 없으면 첫 요소가memo가 되고 두 번째 요소부터 반복합니다. 빈 컬렉션에 초기값 없이 사용 시nil을 반환할 수 있으므로, 항상 초기값을 명시하는 것이 중요합니다.
inject vs. reduce: 동일 기능, 다른 이름
이 두 메서드는 기능적으로 완전히 동일한 별칭입니다. inject는 Ruby의 원래 이름이며, reduce는 Ruby 1.8.7에 추가되어 “하나의 값으로 축소” 의도를 명확히 합니다. 관례적으로 수학적 계산에는 reduce를, 해시와 같은 데이터 구조 구축에는 inject를 사용하는 경향이 있습니다.
주요 활용 사례 및 주의사항
-
활용 사례: 배열 합계(
numbers.inject(:+)), 해시 생성(pairs.inject({}) { |memo, (k, v)| memo[k] = v; memo }) 등 집계 및 데이터 구조 구축에 유용합니다. -
누산기 반환: 블록 내에서
memo를 변경하더라도, 변경된memo객체를 명시적으로 반환해야 합니다.
each_with_object와의 비교
each_with_object는 객체 구축 시 누산기를 명시적으로 반환할 필요가 없어 특정 상황에서 더 간결합니다. reduce는 블록의 반환 값이 다음 누산기가 될 때 적합하며, each_with_object는 객체 변형에 더 효율적입니다.