如何在Scala中提取Array [String]的元素?

san*_*4ka 0 arrays scala

假设我们有一个数组:

val arr = Array("Id:1; Apple; Red; 2; Out",
                "Id:2; Banana; Yellow; 5",
                "Id:3; Peach; Red; 3",
                "Id:4; Grape; Green; 5; Out")
Run Code Online (Sandbox Code Playgroud)

我想在数组的每个元素上应用一个函数,它提取水果类型和数字并返回一个Map.这种情况下的输出是:

(Apple, 2)
(Banana, 5)
(Peach, 3) 
(Grape, 5)
Run Code Online (Sandbox Code Playgroud)

我试过了:

val pairMap = arr.foreach(r => r.split(";")(1) zip r.split(";")(3))
Run Code Online (Sandbox Code Playgroud)

但我总是得到 Unit

thw*_*gan 6

您的代码实际上有两个错误.

首先,正如你所指出的那样,你正在使用foreach(返回Unit)而不是map(返回一个Object).

其次,你正在使用zip你的foreach函数,它结合了两个集合,如下所示:

val arr1 = Seq("Apple", "Peach", "Banana")
val arr2 = Seq("Red", "Red", "Yellow")

val arr3 = arr1 zip arr2 // = Seq(("Apple", "Red"), ("Peach", "Red"), ("Banana", "Yellow"))
Run Code Online (Sandbox Code Playgroud)

您的代码应如下所示:

val arr = Array("Id:1; Apple; Red; 2; Out",
  "Id:2; Banana; Yellow; 5",
  "Id:3; Peach; Red; 3",
  "Id:4; Grape; Green; 5; Out")

arr.map(r => (r.split(";")(1), r.split(";")(3)))
Run Code Online (Sandbox Code Playgroud)

或者通过仅拆分一次来提高效率:

arr.map { r =>
  val t = r.split(";")
  (t(1), t(2))
}
Run Code Online (Sandbox Code Playgroud)

你可能不想要白色空格,所以:

arr.map { r =>
  val t = r.split(";")
  (t(1).trim(), t(2).trim())
}
Run Code Online (Sandbox Code Playgroud)

只是添加这个因为我认为正则表达式也是一个很好的选项,用于字符串处理和一个简洁的功能以及scala的模式匹配:

val regEx = "[^;]+; ([^;]+); [^;]+; ([^;]+).*".r

arr collect {
  case regEx(fruit, number) => (fruit, number)
}
Run Code Online (Sandbox Code Playgroud)

也导致了所需的输出,但对于这个简单的用例可能有点矫枉过正.

  • 这是一个正确的解决方案,为了提高效率,另外一件事就是不使用`map`两次遍历集合两次. (2认同)