728x90
SMALL
가계부 앱을 개발하면서 특정 조건에 맞는 거래 내역을 추려야 할 때가 많습니다.
예를 들어, 이번 달에 발생한 지출만 보고 싶다거나, 7월 한 달 동안의 수입을 계산하고 싶다는 식이죠.
이를 위해 만든 함수가 바로 아래의 filteredTransactions입니다.
🧩 함수 선언
func filteredTransactions(
type: TransactionType? = nil,
in date: Date,
granularity: Calendar.Component = .month
) -> [ExpenseModel] {
let calendar = Calendar.current
let filtered = transactions.filter { transaction in
let matchesType = type == nil || transaction.transaction == type!
let matchesDate = calendar.isDate(transaction.date, equalTo: date, toGranularity: granularity)
return matchesType && matchesDate
}
return filtered
}
🔍 함수의 역할
이 함수는 전체 거래 목록(transactions)에서 다음 조건을 만족하는 항목만 걸러낸 배열을 반환합니다:
- 특정 거래 타입(.income, .expense)인지
- 특정 "날짜 범위(월/일/연도)"와 일치하는지
예를 들어,
"2025년 7월의 지출만 보고 싶어!" 라는 요구를 만족시킬 수 있습니다.
🛠 filter 고차함수 설명
기본 구조
transactions.filter { transaction in
조건을 만족하면 true 반환
}
filter는 배열의 각 요소를 순회하면서, true를 반환하는 항목만 남깁니다.
🔍 조건 분석
1. 타입 비교
let matchesType = type == nil || transaction.transaction == type!
| 상황 | 의미 | 결과 |
| type이 nil | 모든 타입 통과 | true |
| type이 .expense | .expense만 통과 | transaction.transaction == .expense |
| type이 .income | .income만 통과 | transaction.transaction == .income |
💬 쉽게 말하면:
타입을 지정하지 않으면 다 포함시키고, 타입이 지정되면 그것과 일치하는 것만 남긴다.
2. 날짜 비교
let matchesDate = calendar.isDate(transaction.date, equalTo: date, toGranularity: granularity)
- 두 날짜가 .month, .day, .year 단위로 같은지를 판단합니다.
- 예를 들어 granularity: .month이면 같은 달인지만 비교합니다.
| 기준 날짜 | 거래 날짜 | granularity | 일치 여부 |
| 2025-07-01 | 2025-07-15 | .month | ✅ |
| 2025-07-01 | 2025-06-30 | .month | ❌ |
| 2025-07-01 | 2025-07-01 | .day | ✅ |
3. 최종 반환 조건
return matchesType && matchesDate
두 조건이 모두 true일 때만 해당 거래를 반환합니다.
🧪 예제
let transactions = [
ExpenseModel(transaction: .expense, date: 2025-07-15, amount: 10000),
ExpenseModel(transaction: .income, date: 2025-07-01, amount: 50000),
ExpenseModel(transaction: .expense, date: 2025-06-15, amount: 20000)
]
호출 1: .expense, 2025년 7월
filteredTransactions(type: .expense, in: Date("2025-07-01"), granularity: .month)
// ✅ 결과: 첫 번째 항목만 포함됨
호출 2: nil 타입, 2025년 7월
filteredTransactions(type: nil, in: Date("2025-07-01"), granularity: .month)
// ✅ 결과: 첫 번째, 두 번째 항목 포함
호출 3: .income, 2025년 6월
filteredTransactions(type: .income, in: Date("2025-06-01"), granularity: .month)
// ❌ 결과: 없음
📌 마무리
이 filteredTransactions 메서드는 다음과 같은 상황에 매우 유용합니다:
- 특정 달의 수입/지출 내역을 보고 싶을 때
- 통계 데이터를 뽑아야 할 때
- 특정 거래 타입만 따로 보고 싶을 때
filter, Calendar, 옵셔널 비교 등 Swift의 다양한 기능이 종합적으로 활용된 좋은 예시입니다.
728x90
LIST
'Project > ReceiptMind' 카테고리의 다른 글
| 🧩 추가하면 좋은 기능 요약 (3) | 2025.08.04 |
|---|---|
| 💰 Swift reduce 완전 정복: totalAmount() 메서드로 배우는 누적 합계 계산 (0) | 2025.08.03 |
| 🧾 iOS MVVM 가계부 앱 - 거래 내역 조회(Read), 수정(Update), 삭제(Delete) 기능 완벽 구현 (1) | 2025.08.03 |
| 💸 iOS MVVM 가계부 앱 - ViewModel(TransactionViewModel) 구조 완벽 정리 (0) | 2025.08.03 |
| 📦 iOS MVVM 가계부 앱 - Core Data 삭제(Delete) + 이미지 제거까지 정리 (1) | 2025.08.02 |