2017-07-30 91 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