From f218d854646deae063e832761939f161d2afd7da Mon Sep 17 00:00:00 2001 From: Aleksey Troitskiy Date: Thu, 16 Oct 2025 10:39:23 +0300 Subject: [PATCH] add toSeqMap method to NamedTuple syntax --- library/src/scala/NamedTuple.scala | 12 +++++++++++- tests/run/named-tuple-ops.scala | 9 ++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/library/src/scala/NamedTuple.scala b/library/src/scala/NamedTuple.scala index f88f7760365b..2cbaf94835d8 100644 --- a/library/src/scala/NamedTuple.scala +++ b/library/src/scala/NamedTuple.scala @@ -1,5 +1,6 @@ package scala import compiletime.ops.boolean.* +import collection.immutable.{SeqMap, ListMap} import language.experimental.captureChecking @@ -30,7 +31,7 @@ object NamedTuple: import NamedTupleDecomposition.{Names, DropNames} export NamedTupleDecomposition.{ Names, DropNames, - apply, size, init, head, last, tail, take, drop, splitAt, ++, map, reverse, zip, toList, toArray, toIArray + apply, size, init, head, last, tail, take, drop, splitAt, ++, map, reverse, zip, toList, toArray, toIArray, toSeqMap } extension [N <: Tuple, V <: Tuple](x: NamedTuple[N, V]) @@ -209,6 +210,15 @@ object NamedTupleDecomposition: /** An immutable array consisting of all element values */ inline def toIArray: IArray[Object] = x.toTuple.toIArray + /** An immutable map consisting of all element values preserving the order of fields. + * Keys are the names of the elements. + */ + inline def toSeqMap: SeqMap[String, Tuple.Union[V]] = + inline compiletime.constValueTuple[N].toList match + case names: List[String] => + ListMap.from(names.iterator.zip( + x.toTuple.productIterator.asInstanceOf[Iterator[Tuple.Union[V]]] + )) end extension /** The names of a named tuple, represented as a tuple of literal string values. */ diff --git a/tests/run/named-tuple-ops.scala b/tests/run/named-tuple-ops.scala index 8c6db6f2fa1c..ffb77fe72c79 100644 --- a/tests/run/named-tuple-ops.scala +++ b/tests/run/named-tuple-ops.scala @@ -1,5 +1,6 @@ //> using options -source future import scala.compiletime.asMatchable +import scala.collection.immutable.{ListMap, SeqMap} type City = (name: String, zip: Int, pop: Int) type Raw = (String, Int, Int) @@ -82,7 +83,9 @@ type Labels = (x: String, y: String) val _: List[String | Int] = cityFields assert(cityFields == List("Lausanne", 1000, 140000)) - val citArr = city.toArray - val _: List[String | Int] = cityFields - assert(cityFields == List("Lausanne", 1000, 140000)) + val cityArr = city.toArray + assert(cityArr.sameElements(Array("Lausanne", 1000, 140000))) + val cityMap = city.toSeqMap + val _: SeqMap[String, String | Int] = cityMap + assert(cityMap == ListMap("name" -> "Lausanne", "zip" -> 1000, "pop" -> 140000))