英文:
How to convert List[String] to Strings in Scala
问题
我现在正在努力学习Scala。
我有一个映射,其中值是字符串列表 Map[String, List[String]],我想获取值并用逗号分隔以作为参数传递给一个函数。
我有以下代码:
def blah(myMap: Map[String, List[String]]) {
var test = List() // 我试图创建一个新对象并附加到这个列表
test ::= myMap.keys.foreach(key => new foo().withKey(key).withValues(myMap.get(key)))
}
我目前的问题在于 withValues 部分,因为我想要的不是值的数组,我只想要用逗号分隔的值,就像 withValue(value1, value2, ...) 一样。我该如何实现这一点?另外,我附加到列表的方式是否正确?
为了明确我的目标,我想让我的变量 test 类似于:
val test = List(new foo().withKey(key).withValues(value1, value2),
new foo().withKey(key2).withValues(value3),
new foon().withKey(key3).withValues(value4))
然而,因为我试图使这个通用化,我不知道函数将接收的键和值的数量,所以我尝试使用for循环。
英文:
I am struggling with Scala right now.
I have a map where the values is a list of strings Map[String, List[String]] I want to get value and separate with comma to pass as argument to a function.
I have the following
def blah (myMap: Map[String, List[String]]) {
var test = List() // I am trying to create a new object and append to this List
test ::= myMap.keys.foreach( key => new foo().withKey(key).withValues(myMap.get(key)))
}
My problem right now is in the withValues part because what I want is not array of values, I just want the values separated by comma like withValue(value1, value2, ...)
How can I accomplish that? Also is the way I am appending to the list correct?
Just to be clear what I am trying to do it's for my variable test to be something like
val test = List(new foo().withKey(key).withValues(value1, value2),
new foo().withKey(key2).withValues(value3),
new foon().withKey(key3).withValues(value4))
However, because I am trying to make this general where I don't know the number of keys and values the function will get, I am trying to use the for loop.
答案1
得分: 1
要实现withValue(value1, value2, ...),你可以定义你的函数如下:def withValues(values: String*),例如:
def withValues(values: String*): Unit = {
values.foreach(println)
}
然后你可以调用这个函数:
scala> withValues("a")
a
scala> withValues("a", "b")
a
b
scala> val list = List("a", "b")
list: List[String] = List(a, b)
scala> withValues(list:_*)
a
b
但如果你想要传递列表中的所有元素,我认为更简单的方法是将withValues定义为def withValues(values: List[String]),然后Foo类和blah函数如下:
class Foo {
def withKey(key: String): Foo = {
// 做一些操作 ...
println(key)
this
}
def withValues(values: List[String]): Foo = {
// 做一些操作 ...
values.foreach(println)
this
}
}
def blah(myMap: Map[String, List[String]]): List[Foo] = {
myMap.map { case(k,v) => new Foo().withKey(k).withValues(v) }.toList
}
调用blah函数:
scala> blah(Map("a" -> List("1"), "b" -> List("2", "3")))
a
1
b
2
3
res12: List[Foo] = List(Foo@636d4cdc, Foo@565b77ba)
英文:
For implementing withValue(value1, value2, ...):
you can define your function such as def withValues(values: String*), for example:
def withValues(values: String*): Unit = {
values.foreach(println)
}
then you can invoke this function:
scala> withValues("a")
a
scala> withValues("a", "b")
a
b
scala> val list = List("a", "b")
list: List[String] = List(a, b)
scala> withValues(list:_*)
a
b
But if you want to pass the all elements in list, I think it is more simple that define withValues as def withValues(values: List[String]), then the class Foo and function blah looks like:
class Foo {
def withKey(key: String): Foo = {
// do something ...
println(key)
this
}
def withValues(values: List[String]): Foo = {
// do something ...
values.foreach(println)
this
}
}
def blah(myMap: Map[String, List[String]]): List[Foo] = {
myMap.map { case(k,v) => new Foo().withKey(k).withValues(v) }.toList
}
invoke blah:
scala> blah(Map("a" -> List("1"), "b" -> List("2", "3")))
a
1
b
2
3
res12: List[Foo] = List(Foo@636d4cdc, Foo@565b77ba)
答案2
得分: 1
Variadic functions like:
def foo(strings: String*): Unit = ()
are intended to be called like
foo()
foo("value1")
foo("value1", "value2")
//...
However, these Type* are Seq[Type] underneath, so these lists of values are wrapped in Seq and then a single value is passed down.
If you already have a collection to pass there, you need it to be Seq, then the compiler won't complain when you do:
val list: List[String] = List("value")
foo(list.toSeq: _*) // : _* tells compiler it's a vararg
// instead of a single value to wrap in Seq
In Scala 3, as well as Scala 2.12/2.13 with -Xsource:3 flag set up in your build tool, you can use shorter syntax:
val list: List[String] = List("value")
foo(list.toSeq*)
If the type is already Seq you can skip .toSeq (while Lists, Vectors etc are subtypes of Seq, this particular interface often complains if you don't upcast collection to Seq).
Long story short, your code can be implemented as
// Scala 2 without -Xsource:3 flag
val test = myMap.map { case (key, values) =>
new foo().withKey(key).withValues(values.toSeq: _*)
}.toList
// Scala 2.12/2.13 with -Xsource:3, Scala 3
val test = myMap.map { case (key, values) =>
new foo().withKey(key).withValues(values.toSeq*)
}.toList
英文:
Variadic functions like:
def foo(strings: String*): Unit = ()
are intended to be called like
foo()
foo("value1")
foo("value1", "value2")
//...
However, these Type* are Seq[Type] underneath, so these lists of values are wrapped in Seq and then a single value is passed down.
If you already have a collection to pass there, you need it to be Seq, then the compiler won't complain when you do:
val list: List[String] = List("value")
foo(list.toSeq: _*) // : _* tells compiler it's a vararg
// instead of a s single value to wrap in Seq
In Scala 3, as well as Scala 2.12/2.13 with scalacOptions += "-Xsource:3" flag set up in your build tool, you can use shorter syntax:
val list: List[String] = List("value")
foo(list.toSeq*)
If the type is already Seq you can skip .toSeq (while Lists, Vectors etc are subtypes of Seq, this particular interface often complains if you don't upcast collection to Seq).
Long story short, your code can be implemented as
// Scala 2 without -Xsource:3 flag
val test = myMap.map { case (key, values) =>
new foo().withKey(key).withValues(values.toSeq: _*)
}.toList
// Scala 2.12/2.13 with -Xsource:3, Scala 3
val test = myMap.map { case (key, values) =>
new foo().withKey(key).withValues(values.toSeq*)
}.toList
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论