Scala:用于匹配List中的int的循环

时间:2017-02-19 17:38:12

标签: scala

Scala新手。我正在迭代一次for循环100次。 10次​​我想要满足条件'a'和90次条件'b'。但是我希望10 a随机出现。

我能想到的最好的方法是创建一个10个随机整数的val,然后循环1到100个整数。

例如:

val z = List.fill(10)(100).map(scala.util.Random.nextInt)

z: List[Int] = List(71, 5, 2, 9, 26, 96, 69, 26, 92, 4)

然后像:

for (i <- 1 to 100) {
  whenever i == to a number in z: 'Condition a met: do something'
else {
   'condition b met: do something else'
  }
}

我尝试使用contains==以及=!但似乎没有任何效果。我怎么能这样做?

2 个答案:

答案 0 :(得分:5)

你生成的随机数可能会产生重复......是吗?以下是如何轻松生成10个唯一数字1-100(通过生成1-100的随机洗牌序列并进入前10个):

val r = scala.util.Random.shuffle(1 to 100).toList.take(10)

现在您可以简单地将1-100范围划分为随机生成的列表中包含的范围和不包含的范围:

val (listOfA, listOfB) = (1 to 100).partition(r.contains(_))

现在用这两个列表做任何你想做的事,例如:

println(listOfA.mkString(","))
println(listOfB.mkString(","))

当然,您可以随时直接浏览列表:

(1 to 100).map {
  case i if (r.contains(i)) => println("yes: " + i) // or whatever
  case i => println("no: " + i)
}

你认为简单的for循环实际上并不是一个。这是一种理解,它是一种语法糖,可以解释为地图,平面图和过滤器的链式调用。是的,它可以像使用经典的for循环一样使用,但这只是因为List实际上是一个monad。如果你想用惯用的Scala方式(&#34;功能&#34;方式)做一些事情,你应该避免尝试编写经典迭代for循环并且更喜欢获取数据的集合然后映射其元素以执行您需要的任何内容。请注意,集合后面有一个非常丰富的库,允许您调用partition等酷炫方法。

编辑(完整性):

此外,你应该避免副作用,或者至少将它们推到尽可能远的路上。我在谈论我的答案中的第二个例子。让我们说你真的需要记录那些东西(你会使用记录器,但是println对于这个例子来说已经足够了)。这样做很糟糕。顺便说一下,在这种情况下你可以使用foreach而不是map,因为你没有收集结果,只是执行副作用。

好的方法是通过将每个元素修改为适当的字符串来计算所需的东西。因此,计算所需的字符串并将其累积到results

val results = (1 to 100).map {
  case i if (r.contains(i)) => ("yes: " + i) // or whatever
  case i => ("no: " + i)
}

// do whatever with results, e.g. print them

现在results包含一百个&#34;是x&#34;和&#34;没有x&#34;字符串,但你没有做出丑陋的事情,并在映射过程中执行日志作为副作用。相反,您将集合的每个元素映射到相应的字符串(请注意,原始集合保持不变,因此如果(1到100)存储在某个值中,它仍然存在;映射会创建一个新集合),现在你可以用它做任何你想做的事,例如将它传递给记录器。是的,在某些时候你需要做&#34;丑陋的副作用&#34;并记录这些东西,但至少你会有一个特殊的代码部分,你不会把它混合到你的映射逻辑中,它检查数字是否包含在随机序列中。

答案 1 :(得分:3)

(1 to 100).foreach { x =>
  if(z.contains(x)) {
    // do something
  } else {
    // do something else
  }
}

或者您可以使用部分功能,如下所示:

(1 to 100).foreach {
  case x if(z.contains(x)) => // do something
  case _ => // do something else
}