0

下面的代码将一个字符串转换成它的二进制表示,所以

1 = 1,1,0,0
2 = 1,1,1,0
3 = 1,1,0,1
4 = 1,1,0,0

 Returns

4-->1100
1-->1100
2-->1110
3-->1101

编码 :

import scala.collection.immutable.HashMap

object BinaryRepFunctional extends Application {
  val userDetails = HashMap("1" -> "ab",
                            "2" -> "abc",
                            "3" -> "abd",
                            "4" -> "ab")
  val lettersToCheck = "abcd"

  def getBinaryRepresentation = userDetails.mapValues(
      string => lettersToCheck.map(
          letter => if (string.contains(letter)) '1' else '0'))

  getBinaryRepresentation foreach ( (t2) => println (t2._1 + "-->" + t2._2))
}

这是 mapValues 的签名:

override def mapValues[C](f: B => C): Map[A, C] = 
  new MappedValues(f) with DefaultMap[A, C]

这是 Map 的签名,因此它接受一个函数参数并将这个函数应用于被调用的集合中的每个条目。

  def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
    def builder = { // extracted to keep method size under 35 bytes, so that it can be JIT-inlined
      val b = bf(repr)
      b.sizeHint(this)
      b
    }
    val b = builder
    for (x <- this) b += f(x)
    b.result
  }

函数 getBinaryRepresentation 是否可以更明确,因为我很难理解它是如何工作的?

4

2 回答 2

2

如果您不了解getBinaryRepresentation其当前形式,这可能是因为您不熟悉函数式编程概念吗?

map方法通常从Ato获取一个函数B,并将其应用于 s 集合的每个元素,A以创建Bs 集合。例如,给定一个Function1[Int, Int]定义为x => x + 1(即增量运算符),这可以映射到一个集合[1, 7, 42]上以给出 [ 2, 8, 43]。或者考虑

val lengthFn: Function1[String, Int] = { s => s.length }
val myColl = List("London", "Paris")
myColl map lengthFn   // returns List(6, 5)

这就是地图的作用。 mapValues非常相似 - 它只是一个专门的版本,作用于 aMap并转换该 Map 中的每个值。所以扩展上面的例子:

val capitals = Map("England" -> "London", "France" -> "Paris")
capitals mapValues lengthFn    // returns Map("England" -> 6, "France" -> 5)

如果您理解这一点,那么 的定义getBinaryRepresentation就很简单了。它获取userDetails地图,并将转换应用于其每个值(因此结果将是具有相同键但值不同的地图)。

应用于每个值的函数string

lettersToCheck.map(letter => if (string.contains(letter)) '1' else '0'))

这再次应用了映射,这次是在lettersToCheck列表上(aString是 a List[Char])。每个字符依次根据函数进行转换:

if (string.contains(letter)) '1' else '0'

因此列表中的每个字母都映射到'1''0',具体取决于是否string包含它。这意味着根据每个键中包含的字母,应用于每个值的映射结果将是一个完全由 1 和 0 组成的四个字符的字符串。

所以整个事情的结果是一个 Map ,其中的值是从内部函数返回的这些四个字符的 1 和 0 字符串。当您了解它时,这很简单,但是我可以理解,如果您只是按照实现中的代码行map而不理解它的含义,那将是令人困惑的。

于 2013-08-29T15:55:39.050 回答
0

您的userDetails地图包含每个条目12等的结果表示,但位被字母替换。例如,对于键3,值是abd表示应该设置左起第 1、第 2 和第 4 位(从 1 开始)。该函数getBinaryRepresentation遍历abcd存储在lettersToCheck每个字母中的字母,插入结果字符串01取决于该字母是否出现在相应的条目中。

鉴于位串最多为 4 位长,将 1 和 0 的字符串直接存储在映射中并完全避免任何翻译会简单得多。您的代码变得如此简单:

object BinaryRepFunctional extends Application {
  val userDetails = HashMap("1" -> "1100",
                        "2" -> "1110",
                        "3" -> "1101",
                        "4" -> "1100")
  userDetails foreach ( (t2) => println (t2._1 + "-->" + t2._2))
}
于 2013-08-29T15:38:28.073 回答