Scala,让我的循环功能更强大

Pen*_*gin 5 functional-programming scala scala-2.8

我正在努力减少像Java一样编写Scala(2.8)的程度.这是我遇到的问题的简化.您能否建议改进我的"功能更强大"的解决方案?

变换地图

val inputMap = mutable.LinkedHashMap(1->'a',2->'a',3->'b',4->'z',5->'c')
Run Code Online (Sandbox Code Playgroud)

通过丢弃值为'z'的任何条目并在遇到它们时索引字符

第一次尝试

var outputMap = new mutable.HashMap[Char,Int]()
var counter = 0
for(kvp <- inputMap){
  val character = kvp._2
  if(character !='z' && !outputMap.contains(character)){
    outputMap += (character -> counter)
    counter += 1
  }
}
Run Code Online (Sandbox Code Playgroud)

第二次尝试(不是更好,但使用不可变的地图和'foreach')

var outputMap = new immutable.HashMap[Char,Int]()
var counter = 0
inputMap.foreach{
  case(number,character) => {
    if(character !='z' && !outputMap.contains(character)){
      outputMap2 += (character -> counter)
      counter += 1
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Arj*_*jan 11

更好的解决方案:

inputMap.toList.filter(_._2 != 'z').map(_._2).distinct.zipWithIndex.toMap
Run Code Online (Sandbox Code Playgroud)


Aar*_*rup 9

我发现这个解决方案比arjan更简单:

inputMap.values.filter(_ != 'z').toSeq.distinct.zipWithIndex.toMap
Run Code Online (Sandbox Code Playgroud)

个别步骤:

inputMap.values       // Iterable[Char]   = MapLike(a, a, b, z, c)
   .filter(_ != 'z')  // Iterable[Char]   = List(a, a, b, c)
   .toSeq.distinct    // Seq[Char]        = List(a, b, c)
   .zipWithIndex      // Seq[(Char, Int)] = List((a,0), (b,1), (c,2))
   .toMap             // Map[Char, Int]   = Map((a,0), (b,1), (c,2))
Run Code Online (Sandbox Code Playgroud)

请注意,您的问题本身并不涉及地图作为输入,因为您只是丢弃了密钥.如果我正在编写这个,我可能会写一个像这样的函数

def buildIndex[T](s: Seq[T]): Map[T, Int] = s.distinct.zipWithIndex.toMap
Run Code Online (Sandbox Code Playgroud)

并将其作为

buildIndex(inputMap.values.filter(_ != 'z').toSeq)
Run Code Online (Sandbox Code Playgroud)


Rex*_*err 5

首先,如果你在功能上这样做,你应该使用不可变的地图.

然后,为了摆脱某些东西,你使用的filter方法:

inputMap.filter(_._2 != 'z')
Run Code Online (Sandbox Code Playgroud)

最后,要进行重新映射,您可以使用值(但作为一个集合)zipWithIndex,它将从零开始计数,然后转换回映射:

inputMap.filter(_._2 != 'z').values.toSet.zipWithIndex.toMap
Run Code Online (Sandbox Code Playgroud)

由于价值的顺序无论如何都不会被保留*,可能是因为订单可能已经使用集合转换再次洗牌并不重要.

编辑:有一个类似的更好的解决方案; 看到Arjan的.假设(*)是错误的,因为它是LinkedHashMap.所以你需要保留秩序,这是Arjan的解决方案所做的.