2017-07-30 67 views
0

我有一个列表并希望添加一个序号来复制元素。Scala:添加序列号以复制列表中的元素

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 
     } 
    } 
    } 
} 

导致:

res120: scala.collection.mutable.ListBuffer[String] 
    = ListBuffer(a____0, a____1, b____0, b____1, b____2, c____0, c____1, d____0) 

搞乱了秩序。此外,如果有一个更简洁的方式,将是伟大的。

回答

0

我认为一个更简洁的方法,保留订单将只是使用Map[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那么你可以使用foldLeft一个元组来保存地图的中间状态:

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 
2

这应该没有任何可变变量。

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 - 以项目的List(在这种情况下List[String])和折叠他们(首发左)到一个单一的项目。
  • (Map[String,Int]().withDefaultValue(0),List[String]()) - 在这种情况下,新项目将是(Map[String,Int], List[String])类型的元组。我们将用一个空的Map和一个空的List来启动元组。我们将调用该元素x。我们还会从前面的计算中收到元组。我们将拨打Map部分m,我们将拨打List部分l
  • m + (x->(m(x)+1)) - 新元组的Map部分通过创建/更新此Stringx)的计数并将其添加到收到的Map来创建。
  • x + "__" + m(x) :: l - 新元组的List部分是通过在头部预先新建String而创建的。
  • }._2.reverse - fold已完成。从元组(第二个元素)中提取List,并将其反转以恢复元素的原始顺序。
+0

请问您能详细解答一下吗? – sam

+0

如果你不介意的话,下面的问题是否可以在不添加__0的情况下离开第一次出现的字符串?特别是因为一些条目没有重复。 – sam

+0

添加说明。有几种不同的方式来添加您的修改请求。最简单的方法是对当前结果进行“映射”,并去掉字符串中的所有“__0”部分。 – jwvh