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]
a
Map[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