如何在Scala中反规范化嵌套映射,反规范化字符串只包含值?
一般来说,我不熟悉Scala和FP,想知道如何在Scala中对嵌套集合进行非规范化。例如,如果我们有考试试卷的数据:如何在Scala中反规范化嵌套映射,反规范化字符串只包含值?,scala,dictionary,functional-programming,denormalization,Scala,Dictionary,Functional Programming,Denormalization,一般来说,我不熟悉Scala和FP,想知道如何在Scala中对嵌套集合进行非规范化。例如,如果我们有考试试卷的数据: Map("subject" -> "science", "questionCount" -> 10, "questions" -> Map("1" -> Map("ques" -> "What is sun?", "answers" -> Map("1" -> "Star", "2" -> "Giant bu
Map("subject" -> "science", "questionCount" -> 10, "questions" ->
Map("1" ->
Map("ques" -> "What is sun?", "answers" ->
Map("1" -> "Star", "2" -> "Giant bulb", "3" -> "planet")
), "2" ->
Map("ques" -> "What is moon?", "answers" ->
Map("1" -> "Giant rock", "2" -> "White lamp", "3" -> "Planet")
)
)
)
当反规范化为字符串时,仅使用值,它可以写为:
science,2,1,What is sun?,Star
science,2,1,What is sun?,Giant bulb
science,2,1,What is sun?,planet
science,2,2,What is moon?,Giant rock
science,2,2,What is moon?,White lamp
science,2,2,What is moon?,Plane
我知道我可以使用map
处理集合中的每个项目,它返回的项目数完全相同。此外,虽然可以使用flatMap
将每个项目处理为多个项目,并返回比集合中更多的项目,但我无法理解如何使用它进行非规范化
还有,是否可以像这样进行部分非规范化
science,2,1,What is sun?,[Star,Giant bulb,planet]
science,2,2,What is moon?,[Giant rock,White lamp,Planet]
使用
Map[String,Any]
类型的嵌套映射将永远不会有什么好处,因为您必须始终强制转换嵌套值
如果每个答案都需要字符串
,可以flatMap
查看问题,然后map
查看答案
def normalize(map: Map[String, Any]): Seq[String] = {
val subject = map("subject")
val questions = map("questions").asInstanceOf[Map[String, Any]]
val size = questions.size // or map("questionCount") ?
val lines = questions.flatMap { case (id, q) =>
val question = q.asInstanceOf[Map[String, Any]]
val answers = question("answers").asInstanceOf[Map[String, Any]]
answers.values.map(answer =>
List(subject, size, id, question("ques"), answer) mkString ","
)
}
lines.toSeq
}
如果您希望每个问题都有一个字符串
(部分非规范化),您可以将问题映射到上
def seminormalize(map: Map[String, Any]): Seq[String] = {
val subject = map("subject")
val questions = map("questions").asInstanceOf[Map[String, Any]]
val size = questions.size // or map("questionCount") ?
val lines = questions.map { case (id, q) =>
val question = q.asInstanceOf[Map[String, Any]]
val answers = question("answers").asInstanceOf[Map[String, Any]]
List(subject, size, id, question("ques"), answers.values.mkString("[", "," , "]")) mkString ","
}
lines.toSeq
}
我们可以使用规范化
和半规范化
作为:
scala> normalize(map).foreach(println)
science,2,1,What is sun?,Star
science,2,1,What is sun?,Giant bulb
science,2,1,What is sun?,planet
science,2,2,What is moon?,Giant rock
science,2,2,What is moon?,White lamp
science,2,2,What is moon?,Planet
scala> seminormalize(map).foreach(println)
science,2,1,What is sun?,[Star,Giant bulb,planet]
science,2,2,What is moon?,[Giant rock,White lamp,Planet]
在问题中,地图条目使用不同:
这里它们必须是序列:Map(“主题”->“科学”,“问题计数”->10,
在这里,他们必须创建不同的行:Map(“1”->“星形”、“2”->“巨型灯泡”…
首先,我建议引入顺序和选择的概念
然后,我将按如下方式实现非规范化:
object Runner3 extends App {
case class Sequence(items: List[(String, Any)])
case class Choices(items: List[Any])
val source = Sequence(List(
"subject" -> "science",
"questionCount" -> 2,
"questions" -> Choices(List(
Sequence(List(
"ques" -> "What is sun?",
"answers" -> Choices(List("Star", "Giant bulb", "planet")))),
Sequence(List(
"ques" -> "What is moon?",
"answers" -> Choices(List("Giant rock", "White lamp", "Planet"))))))))
def denormalize(seq: Sequence): List[List[String]] =
seq.items.map {
case (_, choices: Choices) => denormalize(choices)
case (_, otherValue) => List(List(otherValue.toString))
}.reduceLeft(
(list1: List[List[String]], list2: List[List[String]]) =>
for(item1 <- list1; item2 <- list2) yield item1 ::: item2
)
def denormalize(choices: Choices): List[List[String]] =
choices.items.flatMap {
case seq: Sequence => denormalize(seq)
case otherValue => List(List(otherValue.toString))
}
denormalize(source).foreach(line => println(line.mkString(",")))
}
对象Runner3扩展应用程序{
案例类别顺序(项目:列表[(字符串,任意)])
案例类别选择(项目:列表[任何])
val源=序列(列表(
“主题”->“科学”,
“问题计数”->2,
“问题”->选项(列表)(
顺序(列表)(
“问题”->“太阳是什么?”,
“答案”->选项(列表(“恒星”、“巨型灯泡”、“行星”)),
顺序(列表)(
“月亮是什么?”,
“答案”->选择(列表(“巨石”、“白灯”、“行星”()()())("巨石”、“白灯”、“行星”)()(
def非规范化(seq:Sequence):列表[列表[字符串]]=
seq.items.map{
案例(u,选项:选项)=>非规范化(选项)
大小写(u,otherValue)=>List(List(otherValue.toString))
}约瑟夫特先生(
(列表1:List[List[String]],列表2:List[List[String]])=>
for(item1列表(列表(otherValue.toString))
}
反规范化(source.foreach)(line=>println(line.mkString(“,”))
}