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
partMap
,我们将调用m
partList
l
-通过创建/更新此m+(x->(m(x)+1))
字符串的计数(
)并将其添加到收到的x
映射中,可以创建新元组的
映射
-新元组的x+“_u”+m(x)::l
部分是通过在头部预先挂起一个新的列表
字符串来创建的
-折叠完成。从元组(第二个元素)中提取}.\u 2.反转
,并将其反转以恢复元素的原始顺序列表
上,并去掉字符串的所有“\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)