Scala groupBy + map问题

时间:2018-06-05 12:54:30

标签: scala dictionary scala-collections

此处的实例:Scastie Example

我不明白这是如何运作的。我有一个像这样的元组序列:

val v = Seq(
  ("provider@test.com",2), 
  ("consumer@test.com",2), 
  ("provider@test.com",9), 
  ("provider@test.com",10)
)

我想将它们分组:

v.groupBy{ case(email, id) => id }

这导致:

Map(
  2 -> List(
      (provider@test.com,2),
      (consumer@test.com,2)
  ), 
  10 -> List(
      (provider@test.com,10)
  ), 
  9 -> List(
      (provider@test.com,9)
  )
)

这是完全合理的,但现在如果我再次映射它们:

v.groupBy{ case(email, id) => id}.map{case(id, data) => data.head}.toSeq

我希望结果是:

Vector((provider@test.com,2), (provider@test.com,10), (provider@test.com,9))

但是我得到了:

Vector((provider@test.com,9))

怎么了?

4 个答案:

答案 0 :(得分:2)

这确实有点令人困惑。发生这种情况是因为Map[K, V]上的Map[K', V']也会返回.values对,并且因为您的密钥都是相同的(邮寄地址),所以您只能返回一个值。

使用Iterable可以避免这种情况,Map会返回.map中的v .groupBy { case (_, id) => id } .values .map(_.head) .toList 个值,然后 if ($catagory==="View All") {$catagory=null;} if ($delivery==="either") {$delivery=null;} if ($cond==="both") {$cond=null;} if ($delivery==="collection") { $delivery="no";} if ($delivery==="delivery") {$delivery="yes";} if ($delivery==="local") {$delivery="local";} $query="SELECT * FROM testdata WHERE title LIKE ? AND location LIKE ? AND postcode LIKE ? AND price >=? AND price <=? AND cond LIKE ? AND catagory LIKE ? AND delivery LIKE ? ORDER BY $order $dir"; $stat=$db->prepare($query); $stat->execute(array("%$searchfor%","%$location%","%$postcode%","$pricefrom","$priceto","%$cond%","%$catagory%","%$delivery%"));

Sub splitFiles()
    Dim tempR As Presentation
    Dim opres As Presentation
    Dim L As Long
    Dim oFolder As String
    'requires v. 2010 or later
    On Error Resume Next
    Set opres = ActivePresentation
    Set tempR = Presentations.Add
    tempR.PageSetup.SlideSize = opres.PageSetup.SlideSize
    oFolder = Environ("USERPROFILE") & "\Desktop\Files\"
    MkDir oFolder
    For L = 1 To opres.Slides.Count
        opres.Slides(L).Copy
        tempR.Windows(1).Panes(1).Activate
        Call CommandBars.ExecuteMso("PasteSourceFormatting")
        Call tempR.SaveCopyAs(oFolder & "Slide" & CStr(L) & ".pptx", ppSaveAsOpenXMLPresentation)
        tempR.Slides(1).Delete
    Next L
    tempR.Saved = True
    tempR.Close
End Sub

答案 1 :(得分:2)

当您在map上不小心调用Map时会发生这种情况。 在这种情况下,对

  2 -> List(
      (provider@test.com,2),
      (consumer@test.com,2)
  ), 
  10 -> List(
      (provider@test.com,10)
  ), 
  9 -> List(
      (provider@test.com,9)
  )

转换成对

(provider@test.com,2)
(provider@test.com,10)
(provider@test.com,9)

然后再次插入到新构造的地图中,将值2乘以10然后乘以9.最终结果是Map[String, Int]类型的地图,其中包含一个条目(provider@test.com,9),当然不是你想要的。

请改为:

println(v.groupBy{ case(email, id) => id}.toSeq.map{case(id, data) => data.head})

答案 2 :(得分:0)

当您执行groupBy时,您会获得Map[Int, Seq[(String, Int)]]map方法将对Map[Int, Seq[(String, Int)]]中的每个条目进行操作。如果您只想对可以执行的值进行操作

v.groupBy{ case(email, id) => id}.mapValues(...

答案 3 :(得分:0)

那是错误的,因为您已经如Andrey Tyukin所指出的那样在Map对象上调用了map方法。首先将其转换为列表,然后使用具有适当转换功能的map方法,如下所示:
 这有效:

aaload