Skip to content

Commit a3e2b17

Browse files
authored
named tuple toMap extension method (#23827)
There already are methods `toArray, toList` for `NamedTuple` for collecting elements into collections. I would like to add method `toSeqMap` where keys are names of the elements. For example: ```scala (x = 1, y = true).toSeqMap // SeqMap("x" -> 1, "y" -> true) ``` One obvious usage of this method is debugging code with named tuples (standard `toString` method doesn't show names): ```scala println((x = 1, y = true)) // prints (1, true) println((x = 1, y = true).toSeqMap) // prints SeqMap(x -> 1, y -> true) ```
2 parents b4f8923 + f218d85 commit a3e2b17

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

library/src/scala/NamedTuple.scala

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package scala
22
import compiletime.ops.boolean.*
3+
import collection.immutable.{SeqMap, ListMap}
34

45
import language.experimental.captureChecking
56

@@ -30,7 +31,7 @@ object NamedTuple:
3031
import NamedTupleDecomposition.{Names, DropNames}
3132
export NamedTupleDecomposition.{
3233
Names, DropNames,
33-
apply, size, init, head, last, tail, take, drop, splitAt, ++, map, reverse, zip, toList, toArray, toIArray
34+
apply, size, init, head, last, tail, take, drop, splitAt, ++, map, reverse, zip, toList, toArray, toIArray, toSeqMap
3435
}
3536

3637
extension [N <: Tuple, V <: Tuple](x: NamedTuple[N, V])
@@ -209,6 +210,15 @@ object NamedTupleDecomposition:
209210
/** An immutable array consisting of all element values */
210211
inline def toIArray: IArray[Object] = x.toTuple.toIArray
211212

213+
/** An immutable map consisting of all element values preserving the order of fields.
214+
* Keys are the names of the elements.
215+
*/
216+
inline def toSeqMap: SeqMap[String, Tuple.Union[V]] =
217+
inline compiletime.constValueTuple[N].toList match
218+
case names: List[String] =>
219+
ListMap.from(names.iterator.zip(
220+
x.toTuple.productIterator.asInstanceOf[Iterator[Tuple.Union[V]]]
221+
))
212222
end extension
213223

214224
/** The names of a named tuple, represented as a tuple of literal string values. */

tests/run/named-tuple-ops.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//> using options -source future
22
import scala.compiletime.asMatchable
3+
import scala.collection.immutable.{ListMap, SeqMap}
34

45
type City = (name: String, zip: Int, pop: Int)
56
type Raw = (String, Int, Int)
@@ -82,7 +83,9 @@ type Labels = (x: String, y: String)
8283
val _: List[String | Int] = cityFields
8384
assert(cityFields == List("Lausanne", 1000, 140000))
8485

85-
val citArr = city.toArray
86-
val _: List[String | Int] = cityFields
87-
assert(cityFields == List("Lausanne", 1000, 140000))
86+
val cityArr = city.toArray
87+
assert(cityArr.sameElements(Array("Lausanne", 1000, 140000)))
8888

89+
val cityMap = city.toSeqMap
90+
val _: SeqMap[String, String | Int] = cityMap
91+
assert(cityMap == ListMap("name" -> "Lausanne", "zip" -> 1000, "pop" -> 140000))

0 commit comments

Comments
 (0)