英文:
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 List
s, Vector
s 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 List
s, Vector
s 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论