我在浏览并发现了一个关于String按字符分组的问题,例如:
输入:
"aaabbbccccdd"
Run Code Online (Sandbox Code Playgroud)
会产生以下输出:
"aaa"
"bbb"
"cccc"
"ddd"
Run Code Online (Sandbox Code Playgroud)
我发现了这个建议:
val str = "aaabbbccccdd"[
val list = str.groupBy(identity).toList.sortBy(_._1).map(_._2)
Run Code Online (Sandbox Code Playgroud)
这个identity家伙让我很好奇.我发现它的定义PreDef如下:
identity[A](x: A): A
Run Code Online (Sandbox Code Playgroud)
所以基本上它会返回给出的任何东西,对吧?但这怎么适用于电话groupBy?
我很抱歉,如果这是一个基本问题,那就是功能性编程仍然让我的脑子有点紧张.如果有任何信息可以让我更清楚,请告诉我
4le*_*x1v 11
要理解这一点,只需使用-Xprint:typer选项调用scala repl :
val res2: immutable.Map[Char,String] = augmentString(str).groupBy[Char]({
((x: Char) => identity[Char](x))
});
Run Code Online (Sandbox Code Playgroud)
Scalac将一个简单String转换成StringOps一个子类,TraversableLike其子类有一个groupBy方法:
def groupBy[K](f: A => K): immutable.Map[K, Repr] = {
val m = mutable.Map.empty[K, Builder[A, Repr]]
for (elem <- this) {
val key = f(elem)
val bldr = m.getOrElseUpdate(key, newBuilder)
bldr += elem
}
val b = immutable.Map.newBuilder[K, Repr]
for ((k, v) <- m)
b += ((k, v.result))
b.result
}
Run Code Online (Sandbox Code Playgroud)
因此groupBy包含一个映射,插入字符通过标识函数返回到该映射.
Vin*_*ana 10
这是你的表达:
val list = str.groupBy(identity).toList.sortBy(_._1).map(_._2)
Run Code Online (Sandbox Code Playgroud)
让我们逐个功能逐项.第一个是groupBy,它将使用鉴别器函数传递的键列表对您的String进行分区,在您的情况下,它是标识符.鉴别器功能将应用于屏幕中的每个字符,并且返回相同结果的所有字符将组合在一起.如果我们想将字母a与其余字母分开,我们可以将其x => x == 'a'用作我们的鉴别器功能.这会将你的字符串字符分组到map中返回此函数(true或false):
Map(false -> bbbccccdd, true -> aaa)
Run Code Online (Sandbox Code Playgroud)
通过使用identity,这是一个"好"的方式x => x,我们得到一个地图,其中每个角色在地图中分开,在您的情况下:
Map(c -> cccc, a -> aaa, d -> dd, b -> bbb)
Run Code Online (Sandbox Code Playgroud)
然后,我们在地图转换成一个元组列表(char,String) 与toList.
通过char对它进行排序,sortBy只需保留String即可map获得最终结果.
首先,让我们看一下在字符串上迭代时会发生什么:
scala> "asdf".toList
res1: List[Char] = List(a, s, d, f)
Run Code Online (Sandbox Code Playgroud)
接下来,考虑有时我们想根据对象的某些特定属性对元素进行分组。
例如,我们可以按长度对字符串列表进行分组,如...
List("aa", "bbb", "bb", "bbb").groupBy(_.length)
Run Code Online (Sandbox Code Playgroud)
如果您只是想按项目本身将每个项目分组。您可以这样传递身份函数:
List("aa", "bbb", "bb", "bbb").groupBy(identity)
Run Code Online (Sandbox Code Playgroud)
您可以像这样做一些愚蠢的事情,但这很愚蠢:
List("aa", "bbb", "bb", "bbb").groupBy(_.toString)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9173 次 |
| 最近记录: |