home wiki.fukuchiharuki.me
Menu

#author("2024-03-11T00:38:29+00:00;2023-06-16T12:30:19+00:00","default:haruki","haruki")
#author("2024-04-02T03:53:25+00:00","default:haruki","haruki")
* キーワード [#pfeae7ab]
- Kotlin
- Tuple

* したいこと [#le731617]

PairやTripleはあるが4つ5つの要素のタプルがないので作りたい。

* どうやって [#obf07310]

次のようにtypealiasと拡張プロパティでそれっぽくできるが、分解宣言できないので''素直にデータクラスを作る''のがよいはず。
** 正攻法 [#e63d22ec]

素直にデータクラスを作る。

Tripleの実装と同じようにQuadrupleやQuintupleを作る。
data classにすればcomponentN()も定義されるので分解宣言できる。

 data class Quadruple<out A, out B, out C, out D>(
     val first: A,
     val second: B,
     val third: C,
     val fourth: D
 ) : Serializable {
     override fun toString(): String = "($first, $second, $third, $fourth)".apply {  }
 }
 
 fun <T> Quadruple<T, T, T, T>.toList(): List<T> = listOf(first, second, third, fourth)

 data class Quintuple<out A, out B, out C, out D, out E>(
     val first: A,
     val second: B,
     val third: C,
     val fourth: D,
     val fifth: E,
 ) : Serializable {
     override fun toString(): String = "($first, $second, $third, $fourth, $fifth)"
 }
 
 fun <T> Quintuple<T, T, T, T, T>.toList(): List<T> = listOf(first, second, third, fourth, fifth)

** 変化球 [#d89ec797]

次のようにtypealiasと拡張プロパティでそれっぽくできる(が、分解宣言できないので正攻法のように''素直にデータクラスを作る''のがよいはず)。

 typealias KTuple4<A, B, C, D> = Pair<Pair<Pair<A, B>, C>, D>
 typealias KTuple5<A, B, C, D, E> = Pair<Pair<Pair<Pair<A, B>, C>, D>, E>
 
 @Suppress("UNUSED", "FunctionName")
 fun <A, B, C, D> KTuple(a: A, b: B, c: C, d: D): KTuple4<A, B, C, D> = a to b to c to d
 @Suppress("UNUSED", "FunctionName")
 fun <A, B, C, D, E> KTuple(a: A, b: B, c: C, d: D, e: E): KTuple5<A, B, C, D, E> = a to b to c to d to e
 
 val <A, B, C, D> KTuple4<A, B, C, D>.t1
     @JvmName("tuple4t1")
     get() = first.first.first
 val <A, B, C, D> KTuple4<A, B, C, D>.t2
     @JvmName("tuple4t2")
     get() = first.first.second
 val <A, B, C, D> KTuple4<A, B, C, D>.t3
     @JvmName("tuple4t3")
     get() = first.second
 val <A, B, C, D> KTuple4<A, B, C, D>.t4
     @JvmName("tuple4t4")
     get() = second
 
 val <A, B, C, D, E> KTuple5<A, B, C, D, E>.t1
     @JvmName("tuple5t1")
     get() = first.first.first.first
 val <A, B, C, D, E> KTuple5<A, B, C, D, E>.t2
     @JvmName("tuple5t2")
     get() = first.first.first.second
 val <A, B, C, D, E> KTuple5<A, B, C, D, E>.t3
     @JvmName("tuple5t3")
     get() = first.first.second
 val <A, B, C, D, E> KTuple5<A, B, C, D, E>.t4
     @JvmName("tuple5t4")
     get() = first.second
 val <A, B, C, D, E> KTuple5<A, B, C, D, E>.t5
     @JvmName("tuple5t5")
     get() = second

* つくりかた [#j33c33f1]
*** つくりかた [#s16c1d9a]

 KTuple(1, 1.0, "1", true)

または

 1 to 1.0 to "1" to true


* 参考 [#wd9f6161]
- [[可変長タプル on Kotlin? | KisaragiEffective.github.io:https://kisaragieffective.github.io/blog/entry/10.html]]