Scala:将Map应用于元组列表

时间:2014-12-19 16:38:32

标签: scala dictionary tuples

非常简单的问题:我想做这样的事情:

var arr1: Array[Double] = ...
var arr2: Array[Double] = ...

var arr3: Array[(Double,Double)] = arr1.zip(arr2)

arr3.foreach(x => {if (x._1 > treshold) {x._2 = x._2 * factor}})

我尝试了很多不同的语法版本,但是我失败了所有这些版本。我该怎么解决这个问题?这可不是很难......

谢谢!

6 个答案:

答案 0 :(得分:3)

解决此问题的多种方法,例如考虑使用提供不可变集合collect的{​​{1}},如下所示,

arr4

有了这样的理解,

val arr4 = arr3.collect {
  case (x, y) if x > threshold => (x ,y * factor)
  case v => v 
}

答案 1 :(得分:1)

我想你想做点什么

scala> val arr1 = Array(1.1, 1.2)
arr1: Array[Double] = Array(1.1, 1.2)

scala> val arr2 = Array(1.1, 1.2)
arr2: Array[Double] = Array(1.1, 1.2)

scala> val arr3 = arr1.zip(arr2)
arr3: Array[(Double, Double)] = Array((1.1,1.1), (1.2,1.2))

scala> arr3.filter(_._1> 1.1).map(_._2*2)
res0: Array[Double] = Array(2.4)

答案 2 :(得分:1)

我认为有两个问题:

  1. 您正在使用foreach,其返回Unit,您要使用map,其中会返回Array[B]

  2. 如果要返回新的更新值,则尝试更新不可变值。这是_._2 = _._2 * factor_._2 * factor之间的差异。

  3. 过滤不符合阈值的值:

    arr1.zip(arr2).filter(_._1 > threshold).map(_._2 * factor)
    

    保留所有值,但只乘以符合阈值的值:

    arr1.zip(arr2).map {
      case (x, y) if x > threshold => y * factor
      case (_, y)                  => y
    }
    

答案 3 :(得分:0)

这个怎么样?

arr3.map { case(x1, x2) =>  // extract first and second value
  if (x1 > treshold) (x1, x2 * factor)   // if first value is greater than threshold, 'change' x2
  else (x1, x2)  // otherwise leave it as it is
}.toMap

Scala通常是可用的,这意味着你不会更改值,而是创建新值,例如你不写x._2 = ...,因为元组是不可变的(你不能改变它),但是创建一个新的元组。

答案 4 :(得分:0)

这将满足您的需求。

arr3.map(x => if(x._1 > treshold) (x._1, x._2 * factor) else x)

这里的关键是你可以通过将两个变量放入(..)来从地图lambda表达式返回元组。

编辑:您想要在不创建新数组的情况下更改数组的每个元素。然后你需要做下一个。

arr3.indices.foreach(x => if(arr3(x)._1 > treshold) (arr3(x)._1, arr3(x)._2 * factor) else x)

答案 5 :(得分:0)

你可以这样做,

arr3.map(x => if (x._1 > threshold) (x._1, x._2 * factor) else x)