You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将列表中的多字符串转为Map键?Scala实现单词-页码索引函数的数据格式化问询

Solution to Create a Word-to-Page Index in Scala

Absolutely, you can reformat your data into the desired Map structure! Let's break down the approach step by step, then modify your code to implement it.

Understanding the Problem

Your current splitt variable is a List[(List[String], Int)]—each entry holds all words from a single line and the corresponding page number. We need to transform this into a Map[String, Set[Int]] where every word maps to the set of pages it appears on.

Core Approach

The key idea is to iterate over each entry in your list, then for every word in the entry's word list, update the map to include the current page number for that word. Here's how to do it:

  • Start with an empty map (Map.empty[String, Set[Int]]).
  • For each (wordsList, page) tuple in splitt:
    • For each word in wordsList, add the page number to the word's set in the map. If the word isn't already in the map, create a new entry with a singleton set containing the page.

Modified Code

Here's your updated function with the indexing logic added:

object G {
  def main(args: Array[String]): Unit = {
    val wordIndex = stwórzIndeks()
    // Print the index to verify results
    wordIndex.foreach { case (word, pages) =>
      println(s"$word: ${pages.mkString(", ")}")
    }
  }

  def stwórzIndeks(): Map[String, Set[Int]] = {
    val linie = io.Source
      .fromResource("tekst.txt")
      .getLines
      .toList

    // Zip each line with its original index (starting at 0)
    val zippedLinie: List[(String, Int)] = linie.zipWithIndex

    // Convert each line to (list of words, page number)
    val splitt: List[(List[String], Int)] = zippedLinie.foldLeft(List.empty[(List[String], Int)]) { (acc, curr) =>
      curr match {
        case (line, index) =>
          val words = line.split("\\s+").toList
          // Note: Adjust page calculation if needed. Current logic reverses line order as pages.
          // Use index + 1 if you want first line to be page 1 instead.
          val page = zippedLinie.length - index
          (words, page) +: acc
      }
    }

    // Build the final word-to-page map
    splitt.foldLeft(Map.empty[String, Set[Int]]) { (acc, entry) =>
      val (words, page) = entry
      words.foldLeft(acc) { (map, word) =>
        // Update the map: add page to the word's set (create set if word is new)
        map.updated(word, map.getOrElse(word, Set.empty) + page)
      }
    }
  }
}

Key Explanations

  • Map Construction: The inner foldLeft over words takes the current map and updates each word's entry. map.getOrElse(word, Set.empty) retrieves the existing set of pages for the word (or an empty set if the word is new), then we add the current page to that set.
  • Page Number Adjustment: Your current code uses zippedLinie.length - index which treats the first line of the file as the last page. If you want the first line to correspond to page 1, change this calculation to index + 1.

Optional Robustness Improvements

To make your index more accurate, consider adding word normalization:

  • Convert all words to lowercase so "Hello" and "hello" are treated as the same key.
  • Remove punctuation (e.g., commas, periods) from words. For example:
    val cleanedWord = word.toLowerCase.replaceAll("[^a-zA-Z0-9]", "")
    
    Use cleanedWord instead of the original word when updating the map to ensure consistent keying.

内容的提问来源于stack exchange,提问作者floppalover

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 14:47:31