当前位置: 首页 > 知识库问答 >
问题:

在Scala数独生成器中过滤嵌套列表和列表项

乐正心水
2023-03-14

作为数独生成器的一部分,我有一个用于过滤嵌套列表的函数,以便只返回某些索引的内部列表以及这些列表中某些索引的内部列表元素。其思想是返回一个List[Int],其中包含一个3x3正方形的值,该正方形取自一个9x9数独拼图,表示为List[List[Int]],作为函数的参数提供。

我尝试了两种方法,但都未能始终如一地发挥作用。一种方法尝试从列表中筛选出某些子列表,然后从其余列表中筛选出项目。此函数完全适用于某些索引,但对于其他索引,它将从某些子列表中过滤过多或过少的索引值,但不是全部:

def getGroup(indexX: Int, indexY: Int, puzzle: List[List[Int]]): List[Int] = {
  val groupX = { //determining row coordinate
  if(indexX <= 2) 2
  else if(indexX <= 5) 5
  else 8
  }
  val groupY = { //determining column coordinate
  if(indexY <= 2) 2
  else if(indexY <= 5) 5
  else 8
  }
  // Using filter
  val subsection: List[List[Int]] = puzzle.filter(x => puzzle.indexOf(x) <= groupX && puzzle.indexOf(x) >= groupX - 2) 
  // This sometimes filters out too many or too few items
  val group: List[List[Int]] = subsection.map(x => x.filter(y => x.indexOf(y) <= groupY && x.indexOf(y) >= groupY - 2))

  val result = group.flatten
  println("subsection " + subsection)
  println("group " + group)
  result
}

下面是一个测试列表[List[Int]]的一些输出,可以通过打印显示结果。我不明白为什么在同一个函数调用中从一些子列表中过滤出不正确的索引,而不是全部。我不认为我只是选择了错误的索引,否则对于同一个函数调用上的所有子列表,它应该以同样的方式不正确。

test: List[List[Int]] = List(List(0, 2, 3, 4, 5, 6, 7, 8, 9), List(1, 2, 3, 4, 5, 6, 7, 8, 9), List(2, 2, 3, 4, 5, 6, 7, 8, 9), List(3, 2, 3, 4, 5, 6, 7, 8, 9), List(4, 2, 3, 4, 5, 6, 7, 8, 9), List(5, 2, 3, 4, 5, 6, 7, 8, 9), List(6, 2, 3, 4, 5, 6, 7, 8, 9), List(7, 2, 3, 4, 5, 6, 7, 8, 9), List(8, 2, 3, 4, 5, 6, 7, 8, 9))

scala> getGroup(2,2,test)
subsection: List(List(0, 2, 3, 4, 5, 6, 7, 8, 9), List(1, 2, 3, 4, 5, 6, 7, 8, 9), List(2, 2, 3, 4, 5, 6, 7, 8, 9))
group: List(List(0, 2, 3), List(1, 2, 3), List(2, 2, 3))
res12: List[Int] = List(0, 2, 3, 1, 2, 3, 2, 2, 3) //Correct 

scala> getGroup(2,7,test)
subsection: List(List(0, 2, 3, 4, 5, 6, 7, 8, 9), List(1, 2, 3, 4, 5, 6, 7, 8, 9), List(2, 2, 3, 4, 5, 6, 7, 8, 9))
group: List(List(7, 8, 9), List(7, 8, 9), List(7, 8, 9))
res13: List[Int] = List(7, 8, 9, 7, 8, 9, 7, 8, 9) //Correct 

scala> getGroup(7,7,test)
subsection: List(List(6, 2, 3, 4, 5, 6, 7, 8, 9), List(7, 2, 3, 4, 5, 6, 7, 8, 9), List(8, 2, 3, 4, 5, 6, 7, 8, 9))
group: List(List(7, 8, 9), List(8, 9), List(7, 9)) //Missing a 7 and an 8
res14: List[Int] = List(7, 8, 9, 8, 9, 7, 9) 

scala> getGroup(4,0,test)
subsection: List(List(3, 2, 3, 4, 5, 6, 7, 8, 9), List(4, 2, 3, 4, 5, 6, 7, 8, 9), List(5, 2, 3, 4, 5, 6, 7, 8, 9))
group: List(List(3, 2, 3), List(4, 2, 3, 4), List(5, 2, 3, 5)) //Not enough values filtered out--unwanted 4 and 5
res32: List[Int] = List(3, 2, 3, 4, 2, 3, 4, 5, 2, 3, 5)

另一种方法使用for循环,该循环只会产生符合if条件的值:

def getGroup(indexX: Int, indexY: Int, puzzle: List[List[Int]]): List[Int] = {
         //this portion is the same as above until the for expression:
  val groupX = { //determining row coordinate
    if(indexX <= 2) 2
    else if(indexX <= 5) 5
    else 8
  }
  val groupY = { //determining column coordinate
   if(indexY <= 2) 2
   else if(indexY <= 5) 5
   else 8
 }
    // using for expression
    val group = for(
      outer <- puzzle if puzzle.indexOf(outer) <= groupX && puzzle.indexOf(outer) >= groupX - 2; 
      inner <- outer if outer.indexOf(inner) <= groupY && outer.indexOf(inner) >= groupY - 2) 
        yield inner
  group
}

我已经用这个List[List[Int]]测试了这个函数,在这个列表中,每个列表从它的索引号开始,然后开始计数:

val testGrid = List(List(0,2,3,4,5,6,7,8,9),List(1,2,3,4,5,6,7,8,9),List(2,2,3,4,5,6,7,8,9),
List(3,2,3,4,5,6,7,8,9),List(4,2,3,4,5,6,7,8,9),List(5,2,3,4,5,6,7,8,9),
List(6,2,3,4,5,6,7,8,9),List(7,2,3,4,5,6,7,8,9),List(8,2,3,4,5,6,7,8,9))

然而,输出并不总是正确的:

scala> getGroup(0, 0, testGrid)
res0: List[Int] = List(0, 2, 3, 1, 2, 3, 2, 2, 3) (correct)
scala> getGroup(3,3,testGrid)
res1: List[Int] = List(4, 5, 6, 5, 6, 4, 6) (too few)
scala> getGroup(3,7,testGrid)
res2: List[Int] = List(7, 8, 9, 7, 8, 9, 7, 8, 9) (correct)
scala> getGroup(7,7,testGrid)
res3: List[Int] = List(7, 8, 9, 8, 9, 7, 9) (too few)
scala> getGroup(7,0,testGrid)
res5: List[Int] = List(6, 2, 3, 6, 7, 2, 3, 7, 8, 2, 3, 8) (too many)

对于我为什么会得到这个输出,可能有一个显而易见的答案,但我一直没有找到。我怀疑这与内部循环有关,因为所有indexY小于3的测试都是正确的,不管indexX的值是多少。

如果您能就这两种尝试提供任何反馈,我将不胜感激。我还希望您能考虑其他方法,使该功能更加直观或简洁。

共有1个答案

吉玉宸
2023-03-14

您可以使用。切片按索引过滤列表的一部分。然后. map(x=

def getGroup(indexX: Int, indexY: Int, puzzle: List[List[Int]]): List[Int] = {
  val xStart = indexX / 3 * 3
  val yStart = indexY / 3 * 3
  puzzle.slice(xStart, xStart + 3).map(row => row.slice(yStart, yStart + 3)).flatten
}

 类似资料:
  • 我有一个类似这样的组对象 和如下所示的Item对象

  • 我正在尝试过滤scala中对象列表的列表属性。例如: 用java定义的类 我的过滤器函数返回字符串列表而不是结果列表 UPDATE我想取回listOf中的所有结果,其中每个结果的名称属性被过滤。

  • 问题内容: 我想获取x在嵌套列表中出现的次数。 如果列表是: 还行吧。但是如果列表是: 如何获得1出现的次数?在这种情况下,4。 问题答案: 这是扁平化嵌套序列的另一种方法。将序列展平后,可以很容易地进行检查以找到项目数。 上面的代码打印:

  • 我有一个有趣的两难处境: 我有一门课,假设它叫做文件柜。 FileCabinet存储文件的链接列表,称为“filesInCabinet”。 在每个文件中,还有另一个文件链接列表,称为“relatedFiles”。 所以它看起来像这样,例如: 文件柜1 文件1 文件3 文件3 文件1 文件2 文件2 我遇到的问题是,嵌套列表(“relatedFiles”)包含文件的单独实例,因此实际上更像: 文件柜

  • 问题内容: 我是一名编程新手,在理解python教科书(Magnus Lie Hetland的“ Beginning Python”)中的示例时遇到了一些麻烦。该示例针对的是递归生成器,该生成器旨在展平嵌套列表的元素(具有任意深度): 然后,您将输入嵌套列表,如下所示: 我了解flatten()中的递归如何帮助缩小到此列表的最内层元素“ 1”,但是我不明白的是当“ 1”实际上作为“嵌套”传递回fl

  • 过滤字段的列表,每一个成员应该是数组或对象 $data = [ ['id'=>1, 'name'=>'a'], ['id'=>2, 'name'=>'b'], ]; // 两个毫无意义的实例化写法 $list = new FilterableList; $list = new FilterableList($data); // 只保留 name 字段 $list = new Fi