아래와 같이 날짜에 따라 아이템 요소를 리스트로 반환해야하는 요소들이 있다. 이를테면, '1일 전'이라는 키 값에는 한개의 아이템 요소가 매핑되며, '2주 전'이라는 키 값에는 2개의 아이템 요소가 매핑되어야 한다.
하지만 서버 API에선 위의 데이터들을 단순 내림차순으로만 정렬해주고 있었다. 따라서 이러한 데이터들을 가공 후, 특정 날짜를 키값으로 지정하고 특정 아이템 데이터들을 밸류값으로 지정하는 작업이 진행되어야 했다.
하나의 data class내 존재하는 요소들을 기준으로 해당 아이템들을 그룹화하고 싶을 때, 위 2가지 메서드들을 쓴다. 하지만 평소에 위 두 메서드에 대해 헷갈리곤 했는데, 이참에 정리가 되었다.
결론부터 말하자면 groupBy()
메서드를 사용해야 한다. 이 메서드는 특정 키값을 기준으로 아이템 요소들을 List
형태로 만들어서 반환한다. 반면, associatedBy()
메서드는 키값을 기준으로 아이템 요소들을 그룹화하긴 하지만 단 하나의 요소만 만들어 반환한다. 즉, 아래와 같은 차이점이 존재하는 것이다.
groupBy
: 1:N 방식으로 그룹화할 때 사용한다.associatedBy
: 1:1방식으로 그룹화할 때 사용한다.위 메서드를 사용하여 실행해봤을 때의 결과이다.
[groupBy()]
data class Person(val name: String, val age: Int)
val people = listOf(
Person("Alice", 21),
Person("Bob", 25),
Person("Charlie", 21),
Person("David", 25),
Person("Eve", 30)
)
val groupedByAge = people.groupBy { it.age }
println(groupedByAge)
// 출력 결과:
// {21=[Person(name=Alice, age=21), Person(name=Charlie, age=21)],
// 25=[Person(name=Bob, age=25), Person(name=David, age=25)],
// 30=[Person(name=Eve, age=30)]}
나이를 기준으로 그루핑하고 있다. 이때, 21살 나이인 사람은 'Alice'와 'Charlie'가 있다. 따라서 21이라는 나이를 키값으로 위 두 사람이 리스트 타입으로 매핑된 것을 출력 결과에서 볼 수 있다.
이는 내부 구현체를 보면 좀 더 직관적으로 이해할 수 있다. 반복 가능한 요소를 참조 객체로 수신 후, 마지막 반환하는 라인을 키값으로 지정함과 동시에, 수신받았던 참조 객체 타입을 리스트 형태로 지정할것이라는걸 볼 수 있다. (1:N관계)
[associateBy]
data class Person(val name: String, val age: Int)
val people = listOf(
Person("Alice", 21),
Person("Alice", 22),
Person("Alice", 23),
Person("Bob", 25),
Person("Charlie", 21),
Person("David", 25),
Person("Eve", 30)
)
val associatedByName = people.associateBy { it.name }
println(associatedByName)
// 출력 결과:
// {Alice=Person(name=Alice, age=23),
// Bob=Person(name=Bob, age=25),
// Charlie=Person(name=Charlie, age=21),
// David=Person(name=David, age=25),
// Eve=Person(name=Eve, age=30)}
반면, 위 메서드의 경우, 이름을 통해 그루핑하고 있다. 하지만 Alice라는 동명이인이 3명이고 각자의 나이 또한 다르다. 이런 상황일 때, associateBy
를 통해 그룹화를 진행할 경우, 가장 마지막 요소만 출력 결과로 찍히는것을 확인할 수 있다.
해당 메서드 또한 내부 구현을 확인해보면 쉬운 이해가 가능하다. 반복 가능한 객체를 수신객체로 수신 후, 반환하는 값을 key값으로 지정하고, 이에 수신받았던 객체 타입을 1:1로 지정한다는 것을 볼 수 있다.
groupBy
: 1:N 방식으로 그룹화할 때 사용한다.associatedBy
: 1:1방식으로 그룹화할 때 사용한다.