是否在scala函数中使用嵌套的foreach进行迭代?

时间:2018-04-28 18:49:19

标签: scala loops functional-programming structure scala-collections

我有一个

finals = Set[(String, String)]

init = Array[(String, String), String]

我想要做的是,如果数组 init (String, String)等于决赛设置的元组,请将其添加到Map[(String, String), String]

例如决赛是:

Set[(m1, c1), (m2, c1)]

init 是:

Array[[(m1, c1), n], [(m2, c2), l], (m2, c1), k]]

结果将是:

Map[((m1, c1), n), ((m2, c1), k)]

我的问题是嵌套foreach在scala中是否正确?至于我编写的代码同时迭代这两个结构,没有错误,它有效,但我不知道它是否是一种功能方式。

我的代码是:

init.foreach(i => {
 finals.foreach(j => {
  if (i._1.equals(j))
   { counts += (i._1 -> i._2) }
  })
 })

提前致谢!

3 个答案:

答案 0 :(得分:2)

这是编写此代码的另一种方法

voice_channel = discord.utils.get(ctx.message.server.channels, name="channelname", type=discord.ChannelType.voice)

解释

考虑这类问题的最佳方法是查看您正在执行的基本操作,并在Scala中计算出等效操作。

您需要的主要操作是选择名为counts = init.filter(e => finals.contains(e._1)).toMap 的集合的特定元素,并且Scala操作为init

您正在应用的测试是查看第一个元组是否在另一个集合中,并且Scala操作是filter

最后,您希望将元组集合转换为contains ,并且Scala操作为Map

答案 1 :(得分:0)

以下是使用collect

使用它的功能方法
scala> val x=Set(("m1", "c1"), ("m2", "c1"))
//x: scala.collection.immutable.Set[(String, String)] = Set((m1,c1), (m2,c1))

scala> val y = Array((("m1", "c1"), "n"), (("m2", "c2"), "l"), (("m2", "c1"), "k"))

//y: Array[((String, String), String)] = Array(((m1,c1),n), ((m2,c2),l), ((m2,c1),k))

scala> y.collect{
        case e if x.filter(p=> p._1 == e._1._1 && p._2 == e._1._2).size>0 => e 
     }
//res3: Array[((String, String), String)] = Array(((m1,c1),n), ((m2,c1),k))

答案 2 :(得分:0)

foreach可以正常运行,但counts += ...不是 - 作为副作用,它会改变counts数据结构。

这是一个相当长的答案,导致一个单行,但我试图解释思考过程:

在努力想出一种编写代码的功能方法的时候,我经常发现考虑如何使用它有帮助...

  • 递归
  • 更高级的操作(map,flatMap,reduce,filter,fold,...)

在这种情况下,如果你是想想你如何做map,你可以改写一下:

  

我想要做的是,如果数组终结的(字符串,字符串)等于init集的元组,则将其添加到Map [(String,String),String]中。

(我假设你在你的问题中意外交换了决赛/ init,但在代码位中使用了正确的方法)

为:

我尝试做的是映射数组(String, String)中的finals项,如果其中一项在init中,则返回找到的项目。返回的值存储在counts

然而,在这种情况下,这并不能让你得到你想要的东西 - map要求你为你映射的每个项目返回1个项目,所以你需要改为{{1避免这种约束。

flatMap

然后你只需添加val finals: Set[(String, String)] = Set(("m1", "c1"), ("m2", "c1")) val init: Array[((String, String), String)] = Array((("m1", "c1"), "n"), (("m2", "c2"), "l"), (("m2", "c1"), "k")) val counts = finals.flatMap( finals_item => init.filter(_._1 == finals_item)) /* Set[((String, String), String)] = Set( (("m1", "c1"), "n"), (("m2", "c1"), "k") ) */

.toMap
相关问题