Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala:添加序列号以复制列表中的元素_Scala_Collections - Fatal编程技术网

Scala:添加序列号以复制列表中的元素

Scala:添加序列号以复制列表中的元素,scala,collections,Scala,Collections,我有一个列表,想添加一个序列号来复制元素 val lst=List("a", "b", "c", "b", "c", "d", "b","a") 结果应该是 List("a___0", "b___0", "c____0", "b___1", "c____1", "d___0", "b___2","a___1") 保持原有秩序 到目前为止,我所拥有的: val lb=new ListBuffer[String]() for(i<-0 to lst.length-2) { val l

我有一个列表,想添加一个序列号来复制元素

val lst=List("a", "b", "c", "b", "c", "d", "b","a") 
结果应该是

List("a___0", "b___0", "c____0", "b___1", "c____1", "d___0", "b___2","a___1")
保持原有秩序

到目前为止,我所拥有的:

val lb=new ListBuffer[String]()
for(i<-0 to lst.length-2) {
  val lbSplit=lb.map(a=>a.split("____")(0)).distinct.toList
  if(!lbSplit.contains(lst(i))){
    var count=0
    lb+=lst(i)+"____"+count

    for(j<-i+1 to lst.length-1){
      if(lst(i).equalsIgnoreCase(lst(j))) {
        count+=1
        lb+= lst(i)+"____"+count
      }
    }
  }
}

打乱了秩序。还有,如果有一种更简洁的方法那就更好了。

我认为保持顺序的更简洁的方法就是使用
映射[String,Int]
来保持每次看到特定字符串时的运行总数。然后,您可以直接映射到
lst
,并在每次看到字符串时不断更新映射:

var map = Map[String, Int]()
lst.map { str =>
  val count = map.getOrElse(str, 0) //get current count if in the map, otherwise zero
  map += (str -> (count + 1)) //update the count
  str + "__" + count
}
这将为您提供以下示例:

List(a__0, b__0, c__0, b__1, c__1, d__0, b__2, a__1)

我认为这是最容易阅读的,但是如果你想避免<代码> var <代码>,那么你可以用一个元组使用<代码> FordDouth来保持地图的中间状态:

lst.foldLeft((List[String](), Map[String, Int]())) { case ((list, map), str) =>
  val count = map.getOrElse(str, 0)
  (list :+ (str + "__" + count), map + (str -> (count + 1)))
}._1

这应该在没有任何可变变量的情况下工作

val lst=List("a", "b", "c", "b", "c", "d", "b","a")

lst.foldLeft((Map[String,Int]().withDefaultValue(0),List[String]())){
  case ((m, l), x) => (m + (x->(m(x)+1)), x + "__" + m(x) :: l)
}._2.reverse
// res0: List[String] = List(a__0, b__0, c__0, b__1, c__1, d__0, b__2, a__1)
解释

  • lst.foldLeft
    -获取项目的
    列表(在本例中为
    列表[字符串]
    ),并将它们(从左侧开始)折叠成一个项目
  • (Map[String,Int]()。使用defaultvalue(0),List[String]())
    -在这种情况下,新项将是
    类型的元组(Map[String,Int],List[String])
    。我们将以一个空的
    映射和一个空的
    列表开始元组
  • case((m,l),x)=>
    -每当
    lst
    中的一个元素传入元组计算时,我们将该元素称为
    x
    。我们还将接收来自上一次计算的元组。我们将调用
    Map
    part
    m
    ,我们将调用
    List
    part
    l
  • m+(x->(m(x)+1))
    -通过创建/更新此
    字符串的计数(
    x
    )并将其添加到收到的
    映射中,可以创建新元组的
    映射
  • x+“_u”+m(x)::l
    -新元组的
    列表
    部分是通过在头部预先挂起一个新的
    字符串来创建的
  • }.\u 2.反转
    -折叠
    完成。从元组(第二个元素)中提取
    列表
    ,并将其反转以恢复元素的原始顺序

您能详细说明解决方案吗?如果您不介意的话,下面的问题是,是否可以保留字符串的第一个匹配项,而不在末尾附加u 0?特别是因为有些条目没有重复。添加了解释。有几种不同的方法可以添加修改请求。最简单的方法可能是将当前结果映射到
上,并去掉字符串的所有
“\uu0”
部分。
val lst=List("a", "b", "c", "b", "c", "d", "b","a")

lst.foldLeft((Map[String,Int]().withDefaultValue(0),List[String]())){
  case ((m, l), x) => (m + (x->(m(x)+1)), x + "__" + m(x) :: l)
}._2.reverse
// res0: List[String] = List(a__0, b__0, c__0, b__1, c__1, d__0, b__2, a__1)