运维开发网
广告位招商联系QQ:123077622
 
广告位招商联系QQ:123077622

在Scala中以函数方式迭代表2填充HasSets

运维开发网 https://www.qedev.com 2020-07-31 10:08 出处:网络 作者:运维开发网整理
我正在编写一个 Scala应用程序并尝试以功能方式迭代表(以二维数组的形式).对于表中的每一行,我想用第一列中的所有不同值填充Set,并使用第二列中的所有不同值填充第二个Set. 我尝试了很多方法,但找不到任何解决方法如何以功能方式进行.因为我从迭代中得到2个新变量,所以没有非功能性帮助似乎是不可能的. 这是一个非功能性示例,其中包含可变HashSets,用于包含产品和客户的表: val myIn
我正在编写一个 Scala应用程序并尝试以功能方式迭代表(以二维数组的形式).对于表中的每一行,我想用第一列中的所有不同值填充Set,并使用第二列中的所有不同值填充第二个Set.

我尝试了很多方法,但找不到任何解决方法如何以功能方式进行.因为我从迭代中得到2个新变量,所以没有非功能性帮助似乎是不可能的.

这是一个非功能性示例,其中包含可变HashSets,用于包含产品和客户的表:

val myInputTable =
  Array(Array("Product A","Customer 1"), Array("Product B","Customer 1"),
    Array("Product C","Customer 2"), Array("Product A","Customer 2"))

val productSet = new collection.mutable.HashSet[String]
val customerSet = new collection.mutable.HashSet[String]

for(
  inputLine <- myInputTable;
  inputElement <- inputLine
) {
  if (inputLine.indexOf(inputElement) == 0) {
    productSet.add(inputElement)
  } else {
    customerSet.add(inputElement)
  }
}

println("Product Set:")
productSet.foreach(println)
println("\nCustomer Set:")
customerSet.foreach(println)

有没有办法如何使用不可变集,其他对象或者for-​​yield语法来做到这一点?

感谢您的任何答案或提示,

费利克斯

每当你发现自己尝试FP-ify迭代序列的代码同时更新一些可变状态时,一个好的第一种方法是使用foldLeft:

val myInputTable =
  Array(Array("Product A","Customer 1"), Array("Product B","Customer 1"),
    Array("Product C","Customer 2"), Array("Product A","Customer 2"))

val (products, customers) =
  myInputTable.foldLeft((Set.empty[String], Set.empty[String])) {
    case ((ps, cs), Array(p, c)) => (ps + p, cs + c)
    case ((ps, cs), _) => (ps, cs) // Alternatively fail here.
  }

foldLeft的第一个参数是初始状态.我们想使用两个不可变集,所以我们使用Set.empty [String]的元组. foldLeft的下一个参数是一个函数:

{
    case ((ps, cs), Array(p, c)) => (ps + p, cs + c)
    case ((ps, cs), _) => (ps, cs) // Alternatively fail here.
  }

这应该是从当前累积状态(ps,cs)和每个元素Array(p,c)到下一个状态的函数.它将从左到右应用于集合中的每个函数(因此foldLeft),累积状态更改,并返回状态的最终值.它的工作原理如下:

scala> val (products, customers) =
     |   myInputTable.foldLeft((Set.empty[String], Set.empty[String])) {
     |     case ((ps, cs), Array(p, c)) => (ps + p, cs + c)
     |     case ((ps, cs), _) => (ps, cs) // Alternatively fail here.
     |   }
products: scala.collection.immutable.Set[String] = Set(Product A, Product B, Product C)
customers: scala.collection.immutable.Set[String] = Set(Customer 1, Customer 2)

在某些情况下,可能会有更多特定的组合器允许您更简洁地表达您的操作,但foldLeft是一个很好的通用起点,允许从可变代码到纯功能代码的相当直接的转换.

扫码领视频副本.gif

0

精彩评论

暂无评论...
验证码 换一张
取 消