scala - scala foreach 循环返回列表
问题描述
我是 scala 的新手(基本上是函数式编程)。我正在尝试遍历行列表(可以认为是字符串),其中每个字符串将被传递给不同的 scala 方法,在该方法中我对输入字符串进行一些操作,然后将字符串返回到 for 循环。
下面不是工作代码,但这是我期望的工作。
val input_list = spark.read
.format("com.crealytics.spark.excel")
.option("sheetName" , "SchemaInfo")
.option("useHeader", "true")
.schema(profilerSchema)
.load(path) // this is spark dataframe, which has rows.
val columnNames : List[String] = new List("Hello" , "world");
var outputList = new ListBuffer[String]();
// Here i am iterating the input_list where i pass each ele to getString() method where
// it returns the final string which i want to add to outputList.
input_list.foreach(i => {
val res: String = getString(row, columnNames)
outputList += res;
}));
def getString(row: Row, schemaNames: List[String]) : String = {
// some implementation where it returns a string.
}
下面是我收到的错误消息(丢弃行号。它在 foreach 循环中得到。)。
Error:(57, 14) overloaded method value foreach with alternatives:
(func: org.apache.spark.api.java.function.ForeachFunction[org.apache.spark.sql.Row])Unit <and>
(f: org.apache.spark.sql.Row => Unit)Unit
cannot be applied to (org.apache.spark.sql.Row => scala.collection.mutable.ListBuffer[String])
excel_df.foreach{row => (jsonStrList += convertRowToJSON(row, columnNames))};
我很难写出逻辑。非常感谢任何帮助。
解决方案
input_list.foreach(i => {
val res: String = getString(row, columnNames)
outputList += res;
});
您在 foreach 方法中的函数返回 outputList 值。如果您查看签名,返回值应该是 Unit - 这意味着该方法不返回值。它假设你做了一些不返回任何东西的计算。
您应该使用 map 而不是 foreach。您不需要 foreach 和 outputList 变量。
input_list.map(row => {
// Logic to return the item that you want to compute
})
.toList()
您必须将您的思维方式从声明一个集合然后循环另一个集合的项目并将计算结果添加到第一个集合的命令式样式转变为使用 map/filter 方法的函数式样式。
例子:
List(1,2,3,4,5,6,7,8,9,10)
// filter gives you the list of even numbers between 1 and 10
.filter(i => i % 2 == 0)
// This gives you the squares of the even numbers between 1 and 10
.map(i => i * i)
// This gives the doubles of the squares of the even numbers
.map(i => i * 2)
你也可以这样做:
val evenNumbers = List(1,2,3,4,5,6,7,8,9,10)
// filter gives you the list of even numbers between 1 and 10
.filter(i => i % 2 == 0)
val squares= evenNumbers
// This gives you the squares of the even numbers between 1 and 10
.map(i => i * i)
val doubleSquares = squares
// This gives the doubles of the squares of the even numbers
.map(i => i * 2)
// this will return a tuple with lists when it's the last statement in a function or method.
(squares, doubleSquares)
如您所见,没有声明 ListBuffer 对象。这个例子有点做作,你可以将最后两张地图合二为一,但我想证明一点。您可以进行其他操作,可以按项目分组、排序等。
一般来说,您需要阅读有关 scala 和 FP 的更多信息。这是一个很好的介绍:https ://docs.scala-lang.org/overviews/scala-book/introduction.html和这个:https ://docs.scala-lang.org/overviews/scala-book/passing-函数-around.html。
您也可以在浏览器中尝试:https ://scastie.scala-lang.org 。
推荐阅读
- html - 使用 ::before 时,Chrome 文本未包含在表格中
- javascript - Ajax 调用和 dom 中的 JQuery 函数
- python - 附加到 SQL Express 中的现有表不起作用
- batch-file - 如果“rpc 服务器没有响应”,则批量跳过计算机
- java - JSoup 无法连接到 URL
- c - 图像调整程序输出扭曲的图像
- javascript - 在表格内按行导航时,VoiceOver 无法聚焦输入(或按钮)
- javascript - 流程:无法获取...因为对象文字中缺少属性...
- statistics-bootstrap - 如何在 r 中执行不同类型的引导程序?
- tsql - 在特定条件下生成字符串