我在下面有一個 Scala 串列:
val numList = List(1,2,3,4,5,1,2)
我想獲取串列中相同元素對的索引。輸出應該看起來像(0,5),(1,6)
我怎樣才能實作使用map?
def catchDuplicates(num : List[Int]) : (Int , Int) = {
val count = 0;
val emptyMap: HashMap[Int, Int] = HashMap.empty[Int, Int]
for (i <- num)
if (emptyMap.contains(i)) {
emptyMap.put(i, (emptyMap.get(i)) 1) }
else {
emptyMap.put(i, 1)
}
}
uj5u.com熱心網友回復:
讓我們讓挑戰更有趣一點。
val numList = List(1,2,3,4,5,1,2,1)
現在結果應該類似于(0, 5, 7),(1, 6),這很明顯回傳一個或多個元組是不可行的。回傳 a ListofList[Int]會更有意義。
def catchDuplicates(nums: List[Int]): List[List[Int]] =
nums.zipWithIndex //List[(Int,Int)]
.groupMap(_._1)(_._2) //Map[Int,List[Int]]
.values //Iterable[List[Int]]
.filter(_.lengthIs > 1)
.toList //List[List[Int]]
您還可以添加 a.view以最小化創建的遍歷和中間集合的數量。
def catchDuplicates(nums: List[Int]): List[List[Int]] =
nums.view
.zipWithIndex
.groupMap(_._1)(_._2)
.collect{case (_,vs) if vs.sizeIs > 1 => vs.toList}
.toList
uj5u.com熱心網友回復:
如何使用地圖實作?
你不能。
因為你只想回傳出現兩次的元素的索引;這是一種與map預期截然不同的轉變。
你可以使用foldLeft思想。
object catchDuplicates {
final case class Result[A](elem: A, firstIdx: Int, secondIdx: Int)
private final case class State[A](seenElements: Map[A, Int], duplicates: List[Result[A]]) {
def next(elem: A, idx: Int): State[A] =
seenElements.get(key = elem).fold(
ifEmpty = this.copy(seenElements = this.seenElements (elem -> idx))
) { firstIdx =>
State(
seenElements = this.seenElements.removed(key = elem),
duplicates = Result(elem, firstIdx, secondIdx = idx) :: this.duplicates
)
}
}
private object State {
def initial[A]: State[A] =
State(
seenElements = Map.empty,
duplicates = List.empty
)
}
def apply[A](data: List[A]): List[Result[A]] =
data.iterator.zipWithIndex.foldLeft(State.initial[A]) {
case (acc, (elem, idx)) =>
acc.next(elem, idx)
}.duplicates // You may add a reverse here if order is important.
}
可以這樣使用:
val numList = List(1,2,3,4,5,1,2)
val result = catchDuplicates(numList)
// result: List[Result] = List(Result(2,1,6), Result(1,0,5))
您可以在此處看到運行的代碼。
uj5u.com熱心網友回復:
我認為回傳元組不是一個好的選擇,而您應該嘗試Map-
object FindIndexOfDupElement extends App {
val numList = List(1, 2, 3, 4, 5, 1, 2)
@tailrec
def findIndex(elems: List[Int], res: Map[Int, List[Int]] = Map.empty, index: Int = 0): Map[Int, List[Int]] = {
elems match {
case head :: rest =>
if (res.get(head).isEmpty) {
findIndex(rest, res Map(head -> (index :: Nil)), index 1)
} else {
val updatedMap: Map[Int, List[Int]] = res.map {
case (key, indexes) if key == head => (key, (indexes : index))
case (key, indexes) => (key, indexes)
}
findIndex(rest, updatedMap, index 1)
}
case _ => res
}
}
println(findIndex(numList).filter(x => x._2.size > 1))
}
您可以清楚地看到地圖中的數字(鍵)和相應的索引 -
HashMap(1 -> List(0, 5), 2 -> List(1, 6))
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/339695.html
標籤:斯卡拉
上一篇:spark檢測并提取列值中的模式
下一篇:在Spark中回圈scala串列
