【问题标题】:Some Workaround with scala map() and listscala map() 和列表的一些解决方法
【发布时间】:2016-09-13 21:34:02
【问题描述】:

所以,我得到了一个元组列表,其中元组是 Int 和 List[Int] 的对。我需要在内部列表中添加一项来完成我尝试使用地图功能并且确实喜欢这个

val list = List((7, List(2,4,18)), (10,List (4,8,12)), (12, List (5, 9, 13)))
list.map(e => mapFunction(e,16,10))

上面我想在其列表 16 中插入第一个值为 10 的元组。这是 mapFunction:

 def mapFunction(element: (Int, List[Int]), i: Int, fileID: Int) : (Int, List[Int]) = {
        if (element._1 == fileID) {
            val list2 = element._2 :+ i
            (element._1, list2)
        }
        else
            element
    }

列表 2 包含附加值,但在原始列表中仍保持不变。有什么解决方法吗?

【问题讨论】:

  • 如果你这样做val newList = list.map(e => mapFunction(e,16,10)),这个newList 会是你需要的吗?
  • 不完全是,问题有点广泛。我正在尝试在 scala 中实现倒排位置索引,我的数据结构是index: Map[String, List[(Int, List[Int])]]。由于对于每个术语,我必须为每个文档保留文档ID 和该术语在文档中的位置。所以我的问题是为 docID 添加一个位置。如果我每次只返回新列表,我需要在地图中删除和添加术语,这是愚蠢的。

标签: scala data-structures


【解决方案1】:

这是否符合您的要求?

val lstA = List((7, List(2,4,18)), (10,List (4,8,12)), (12, List (5, 9, 13)))
val lstB = lstA.map{case (n,l) if n == 10 => (n, l :+ 16) ;case e => e}

在第一个 List 上调用 map 不会修改列表。它将创建一个新的、修改后的列表。

将它包装在一个函数中可能是这样的。

// returns new List
def f(lst: List[(Int, List[Int])], i: Int, fileID: Int) : List[(Int, List[Int])] = 
  lst.map{case (n,l) if n == fileID => (n, l :+ i) ;case e => e}

更新

如果你的(Int,List) 元组的Int 部分是一个“fileID”,那么它可能需要在整个元组列表中是唯一的,即你永远不会有List( (10,List(2,4)), (10,List(3,5)) )。如果是这样,那么为什么不使用 Map 而不是元组呢?这将保证唯一性并简化访问内部列表。您可以使用可变的Map 来简化数据插入。

import collection.mutable.{Map => MMap}

def insert(m: MMap[Int, List[Int]], fileID: Int, n: Int): Unit = {
  val newList: List[Int] = m.getOrElseUpdate(fileID, List()) :+ n
  m.update(fileID, newList)
}

如果你有这样的数据集...

val index: Map[String, MMap[Int, List[Int]]] =
  Map("key1" -> MMap(7 -> List(2,4,18), 10 -> List(4,8,12), 12 -> List(5, 9, 13))
    , "key2" -> MMap(8 -> List(2,4,18)))

...你可以像这样更新它。

insert(index("key2"), 19, fileID = 9)
insert(index("key1"), fileID = 10, 16)

现在数据集看起来像这样。

Map(key1 -> Map(7 -> List(2,4,18), 10 -> List(4,8,12,16), 12 -> List(5,9,13))
  , key2 -> Map(8 -> List(2,4,18), 9 -> List(19)))

【讨论】:

  • 不完全是,问题有点广泛。我正在尝试在scala中实现倒排位置索引,我的数据结构是index: Map[String, List[(Int, List[Int])]]。因为对于每个术语,我必须为每个文档保留文档ID 和该术语在文档中的位置。所以我的问题是为 docID 添加一个位置。如果我每次都需要在地图中删除和添加术语时都返回新列表,这很愚蠢,我猜。
  • 我想,差不多就是这样。非常感谢!
【解决方案2】:

你可以使用 for comprehension 来做一个过滤器

val list = List((7, List(2,4,18)), (10,List (4,8,12)), (12, List (5, 9, 13)))
for {
     (k,v) <- list 
       newList = if(k == 10) 90 :: list else v  
    }yield(k,newList)

【讨论】:

    【解决方案3】:

    您可以使用 Scala 标准库 Map 方法巧妙地做到这一点

    val list = List((7, List(2,4,18)), (10,List (4,8,12)), (12, List (5, 9, 13)))
    
    def update(i: Int, fileId: Int, list: List[(Int, List[Int])]): List[(Int, List[Int])] = list.toMap.get(fileId).map(list => map.updated(fileId, i :: list)).getOrElse(map).toList
    

    Scala REPL

    scala>  def update(i: Int, fileId: Int, list: List[(Int, List[Int])]): List[(Int, List[Int])] = list.toMap.get(fileId).map(list => map.updated(fileId, i :: list)).getOrElse(map).toList
    defined function update
    
    scala> update(100, 7, list)
    res16: List[(Int, List[Int])] = List((7, List(100, 2, 4, 18)), (10, List(4, 8, 12)), (12, List(5, 9, 13)))
    

    i 被添加到fileId 的相应列表中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-05
      • 1970-01-01
      • 2014-08-28
      • 2018-10-26
      • 1970-01-01
      • 2012-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多