Scala 处理集合的集合并返回一个平坦的Iterable
我想要这个:Scala 处理集合的集合并返回一个平坦的Iterable,scala,functional-programming,yield,loops,Scala,Functional Programming,Yield,Loops,我想要这个: val input=Set(Set("a","b"),Set("b","c")) 实现此类功能的最佳功能方法是什么? 在嵌套的Iterables中使用yield关键字结果: Map("a"->1,"b"->2,"c"->1) output=for(firstlevel更新:包含使用input.toSeq.flatten的建议 而不是input.toSeq flatMap{{uu.toSeq} 转换为单个值序列 output = for(firstlevel&l
val input=Set(Set("a","b"),Set("b","c"))
实现此类功能的最佳功能方法是什么?
在嵌套的Iterables中使用yield关键字结果:
Map("a"->1,"b"->2,"c"->1)
output=for(firstlevel更新:包含使用input.toSeq.flatten的建议
而不是input.toSeq flatMap{{uu.toSeq}
转换为单个值序列
output = for(firstlevel<-input) yield for(item<-firstlevel) yield item
…组匹配的值
input.toSeq.flatten
…还有伯爵
input.toSeq.flatten groupBy { identity }
哦,天哪,那太难看了
input.toSeq.flatten groupBy { identity } mapValues { _.size }
[编辑]
Collection API确实需要一种方法来“合并”两个地图(或者我是不是忽略了它?)
有了这个,你可以写下如下内容:
def merge[A,B](m1: Map[A,B], m2:Map[A,B])(f: (B,B)=>B):Map[A,B] =
m1.foldLeft(m2)((m,t) =>
m + (t._1 -> m.get(t._1).map(k => f(k,t._2)).getOrElse(t._2)))
[Edit2]
根据凯文的想法,合并可以写成
input.map(_.map(x => x -> 1).toMap).reduceLeft(merge(_,_)(_+_))
看来我的声级还太弱了,最好的表达方式是什么
def merge[A,B](m1: Map[A,B], m2:Map[A,B])(f: (B,B)=>B):Map[A,B] =
m1.keys ++ m2.keys map {k => k ->
List(m1.get(k), m2.get(k)).flatten.reduceLeft(f)} toMap
?如果您想用于理解和屈服:
(o1,o2) match {
case (Some(x),Some(y)) => Some(f(x,y))
case (Some(x), _) => Some(x)
case (_, Some(y)) => Some(y)
case => error("crack in the time-space-continuum")
}
output=for{
(set,idx)为什么不使用这种语法?input.toSeq.flatMap(.toSeq).groupBy(identity).mapValues(.size)其中一些是个人喜好,比如放大括号和制表符的位置与空格的位置,但我发现使用中缀符号编写的代码通常更干净、更容易阅读。另外,我知道你是想写input.toSeq.flatMap(q.toSeq).groupBy(identity).mapValues({code.size)
。这是您的wiki格式。我发现,在SOIt上添加注释时,用反勾符号包装代码会更简单:output={input.toSeq flatten}groupBy{identity}mapValues{{{code.size}
这让我学会了折叠和curried函数,我认为折叠在很多情况下都很好,但在这种情况下,我更喜欢使用Kevin的解决方案,因为它比fold methodScala已经可以进行合并的方法更具声明性和可读性,但您必须显式使用collection.immutable.Map
而不是collection.Map
。然后编写val merged=m1和default m2
,这依赖于Map[K,V]
扩展了A=>B
实际上,这仍然不允许您在合并键上进行迭代。您需要更像{val m1m2=m1和default m2;m1.keys++m2.keys映射{K=>K->m1m2(K)}toMap}
@Kevin:我需要一种方法,当两个映射中都有一个键时,将这些值相加,所以我看不出withDefault在这方面有什么帮助。@Landei:啊,我明白了,可能是某种基于索引的zip,取一个Map[K,V1]
aMap[K,V2]
并返回一个Map[K,(Option[V1],Option[V2])
(o1,o2) match {
case (Some(x),Some(y)) => Some(f(x,y))
case (Some(x), _) => Some(x)
case (_, Some(y)) => Some(y)
case => error("crack in the time-space-continuum")
}
output = for{
(set,idx) <- input.zipWithIndex
item <- set
} yield (item -> idx)
output = for{
set <- input
item <- set
} yield item