문제 1 4개의 Person 타입 객체를 갖는 시퀀스 heroes 를 생성했습니다.
(1) 나이가 가장 젊은 객체를 찾으세요.
(2) 이름 순으로 객체를 정렬하세요.
(3) 미혼인 객체를 모두 찾으세요.
(4) 객체의 평균 나이를 구하세요.
class Person(val name: String,
val age: Int,
val gender: Char,
val martialStatus: Boolean) {
override fun toString() = "$name $age $gender $martialStatus"
}
fun main() {
val heroes = sequenceOf(
Person("홍길동", 21, 'M', false),
Person("신사임당", 47, 'F', true),
Person("유관순", 18, 'F', false),
Person("임꺽정", 33, 'M', true),
)
println(heroes.minByOrNull { it.name }) // 가나다 순으로 첫 번째 객체
// println(heroes.maxByOrNull { it.name })
println(heroes.minByOrNull { it.age }) // 나이 순으로 가장 젊은 객체
// println(heroes.maxByOrNull { it.age })
println(heroes.sortedBy { it.age }.toList()) // 나이를 기준으로 정렬
// println(heroes.sortedByDescending { it.age }.toList())
println(heroes.filter { it.martialStatus }.toList()) // 기혼 객체만을 찾음
// println(heroes.filter { !it.martialStatus }.toList())
val n = heroes.count()
println("나이 평균 = " + heroes.sumOf { it.age / n })
}
문제 2 검색 조건을 클래스로 만들어 최종 검색은 클래스 FindPersonFilters의 메소드 foundPerson()에서 구현하면 됩니다. 아래 예제는 시퀀스 객체 heroes에서 성이 '홍'씨이고, '미혼'인 사람을 찾습니다.
class Person(val name: String, ...) {
override fun toString() = "$name $age $gender $martialStatus"
}
class FindPersonFilters {
var familyName: String = ""
var married: Boolean = false
fun foundPerson(): (Person) -> Boolean {
val p = { p: Person ->
p.name.startsWith(familyName) && p.martialStatus == married
}
return p
}
}
fun main() {
val heroes = listOf(
Person("홍길동", 21, 'M', false), ...)
val filters = FindPersonFilters()
with (filters) {
familyName = "홍"
married = true
}
val found = heroes.filter(filters.foundPerson())
if (found != null && found.isNotEmpty())
println(found.toString())
else
println("not found")
}
문제 3 1부터 시작해 3의 배수를 생성하는 시퀀스([1, 3, 9, 27, 81]를 생성하고, 이 시퀀스를 3진수로 변환하시오. 단, (1, 1), (3, 10), (9, 100), ... )과 같이 10진수 숫자와 3진수 숫자를 같이 출력해야 합니다. associate 메소드를 적용하는 것이 핵심입니다.
fun main() {
val seq = generateSequence(1) { if (it > 50) null else it*3 }
.associate {
val num = it.toString(3)
"$it" to num
}
println(seq.toList())
}
문제 4 리스트 컬렉션 객체 stat 는 어떤 사이트(site)의 웹/앱 방문 통계 데이터를 저장하고 있습니다. 이를 위해 2개의 enum class(SNS, OS)와 1개의 data 클래스(VisitorStatistics)를 정의하고 있습니다.
(1) 운영체제 Windows를 사용해 접속한 사용자들의 평균 방문 시간(duration) 을 구하세요.
(2) 월별 방문 건수 최대인 원소를 구하세요.
(3) mobile 운영체제(ANDROID, IOS)를 사용해 접속한 사례 중 월별 방문 건수가 최대인 원소를 구하세요.
(4) 주별 방문 건수의 총합을 구하세요.
enum class SNS { CACAO, FACEBOOK, TWITTER, YOUTUBE, INSTAGRAM }
enum class OS { WINDOWS, MAC, ANDROID, IOS }
data class VisitorStatistics (
val weeklyVisit: Int, // 주별 방문 건수
val monthlyVisit: Int, // 월별 방문 건수
val duration: Double, // 평균 방문 시간(단위: 분)
val os: OS,
val sns: SNS
)
val stat = listOf(
VisitorStatistics(61, 225, 11.8, OS.WINDOWS, SNS.CACAO),
VisitorStatistics(86, 347, 12.3, OS.IOS, SNS.INSTAGRAM),
VisitorStatistics(98, 391, 12.5, OS.ANDROID, SNS.INSTAGRAM),
VisitorStatistics(76, 248, 16.7, OS.MAC, SNS.YOUTUBE),
VisitorStatistics(59, 233, 16.9, OS.ANDROID, SNS.YOUTUBE),
VisitorStatistics(82, 251, 17.4, OS.WINDOWS, SNS.YOUTUBE),
VisitorStatistics(11, 27, 8.6, OS.WINDOWS, SNS.FACEBOOK),
VisitorStatistics(3, 15, 5.1, OS.IOS, SNS.TWITTER),
)
fun main() {
val avgDuration = stat
.filter { it.os == OS.WINDOWS }
.map(VisitorStatistics::duration)
.average()
println(String.format("%.2f", avgDuration))
println(stat.maxByOrNull { it.monthlyVisit }.toString())
val maxMonthlyVisit = stat
.filter { it.os in setOf(OS.IOS, OS.ANDROID) }
.maxByOrNull { it.monthlyVisit }
println(maxMonthlyVisit.toString())
val totalWeeklyVisit = stat.sumOf { it.weeklyVisit }
println(totalWeeklyVisit.toString())
}
문제 5 문제 4의 답을 메소드 체이닝(method chaining) 방식으로 구현했다면 이를 확장 함수로 구현해 보는 문제입니다.
(1) 문제 4의 "(1) 운영체제 Windows를 사용해 접속한 사용자들의 평균 방문 시간(duration) 을 구하세요."를 확장 함수로 구현해 보세요
fun List<VisitorStatistics>.avgDuration(os: OS) =
filter { it.os == os }.map(VisitorStatistics::duration).average()
fun main() {
println(stat.avgDuration(OS.WINDOWS))
}
(2) (1)번의 확장 함수를 함수 타입을 선언하는 방식으로 수정해서 문제 4의 (3)을 구현해 보세요.
fun List<VisitorStatistics>.modifiedAvgDuration(func: (VisitorStatistics) -> Boolean) =
filter (func).map(VisitorStatistics::duration).average()
fun main() {
val averageWindowDuration = stat
.modifiedAvgDuration { it.os in setOf(OS.IOS, OS.ANDROID) }
println(averageWindowDuration)
}
'코틀린' 카테고리의 다른 글
코틀린: infix expression을 prefix expression으로 변환(2/5) - List 구현 (0) | 2025.01.09 |
---|---|
코틀린: infix expression을 prefix expression으로 변환(1/5) - 문자열 방식 (0) | 2025.01.09 |
코틀린: 5장 테스트에 도전해 보세요 (0) | 2025.01.09 |
코틀린: 시퀀스(Sequence)와 컬렉션(Collection)은 뭐가 다를까요? (0) | 2025.01.09 |
코틀린: Comparable 인터페이스와 Comparator 인터페이스 (0) | 2025.01.09 |