繁体   English   中英

scala foreach循环返回列表

[英]scala foreach loop return list

我是 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 方法中的 function 返回 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 的信息。 This is a good introduction: https://docs.scala-lang.org/overviews/scala-book/introduction.html and this: https://docs.scala-lang.org/overviews/scala-book/passing-功能-around.html

您也可以在浏览器中尝试: https://scastie.scala-lang.org

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM