Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List (Scala)在输出中保持列表的结构_List_Scala_Functional Programming_Nested Lists - Fatal编程技术网

List (Scala)在输出中保持列表的结构

List (Scala)在输出中保持列表的结构,list,scala,functional-programming,nested-lists,List,Scala,Functional Programming,Nested Lists,我需要一些帮助 我一直在研究Scala的功能方面。几乎所有的工作都列在清单上,大部分情况下,我可以解决问题,但我遇到了一个小死胡同。在某些问题上,我无法保持列表的原始形式(结构)。在输出中,所有嵌套列表都被展平。Concatenate::将列表(即原始列表的一个元素)展平,而append:会给我一个编译错误,因为它需要一个泛型T类型(而不是列表) 一个非常简单的示例,其中我想删除与输入匹配的列表的第一个元素: def removeFirst[T](obj: T, list: List[T]):

我需要一些帮助

我一直在研究Scala的功能方面。几乎所有的工作都列在清单上,大部分情况下,我可以解决问题,但我遇到了一个小死胡同。在某些问题上,我无法保持列表的原始形式(结构)。在输出中,所有嵌套列表都被展平。Concatenate
::
将列表(即原始列表的一个元素)展平,而append
会给我一个编译错误,因为它需要一个泛型T类型(而不是列表)

一个非常简单的示例,其中我想删除与输入匹配的列表的第一个元素:

def removeFirst[T](obj: T, list: List[T]): List[T] = {
  if (list isEmpty) Nil
  else{
  val fin: List[T] = list.head match {
    case headAsList: List[T] => if (containsWithNestedLists(obj, headAsList))
      removeFirst(obj, headAsList) ::: list.tail
    else headAsList ::: removeFirst(obj, list.tail)
    case _ => if (list.head == obj) list.tail
    else if (list.tail == List()) List(list.head)
    else list.head :: removeFirst(obj, list.tail)
  }
  fin
  }
}
对于一级深度列表,它可以正常工作,但是 输出结果为
removeFirst(1,List(List(1,2,3),1,2,3,4,5,6))
是List(2,3,1,2,3,4,5,6),理想情况下我想要List(List(2,3),1,2,3,4,5,6))

或者更具体的输入
removeFirst(1,List(List)(2,3,List()),List(1,2,3),1,2,3,4,5,6,List(2,3,List()))
应该有输出=
List(List(2,3,List()),List(2,3),1,2,3,4,5,6,List(1,2,3,List())

我还发现,删除泛型
T
并在其位置使用
Any
确实有效,但我也知道
Any
是一个很大的no-no和一个永久性问题的临时解决方案,因为在其他函数中它没有帮助


据我所知,我还没有在互联网上看到一个有用的解决方案,所以我不得不问。我是否遗漏了什么,需要调试,或者是否有其他功能可以帮助我?我得到的最接近我的答案是以某种方式使用append
,但我可能错了。

您的示例看起来就像是要从列表中删除某个元素(如果它存在的话)。 对于平面列表,您可以执行更简单的操作:

def removeFirst[T](obj: T, list: List[T]) = list match {
  case `obj` :: rest => rest
  case _ => list
}
这将执行以下操作:

> removeFirst(1, List(1, List(1,2,3)))
res57: List[Any] = List(List(1, 2, 3))
> removeFirst(1, List(2, List(1,2,3)))
res58: List[Any] = List(2, List(1, 2, 3))
> removeFirst(List(2,3), List(List(2,3), List(1,2,3)))
res59: List[List[Int]] = List(List(1, 2, 3))
但是,您似乎希望对任意嵌套的列表执行此操作。这是不可能直接实现的,因为Scala无法表示其确切类型。你需要的类型应该是

type NestedList[T] = List[T union NestedList[T]]
Scala没有联合类型,并且您不能以这种方式进行递归定义,因此您也不能这样做:

type NestedList[T] = List[Either[T, NestedList[T]]] 
但是,如果使用类而不是类型,则可以执行此操作:

case class NestedList[T](value: List[Either[T, NestedList[T]]])
现在您可以这样编写算法:

def removeFirst[T](obj: T, list: NestedList[T]): NestedList[T] = {
  val rest = list.value match {
    case Left(`obj`) :: tail => tail
    case __ => list.value
  }
  NestedList(rest.map {
    case Right(r) => Right(removeFirst(obj, r))
    case Left(r) => Left(r)
  })
}
你可以这样做:

> removeFirst(1, NestedList(List(Left(1), Left(2),  Right(NestedList(List(Left(1),Left(3)))))))
res71: NestedList[Int] = NestedList(List(Left(2), Right(NestedList(List(Left(3))))))

当然,构建和分解这些结构有点麻烦。因此,使用一个密封的抽象类和两个case类来构建一个合适的树类,而不是使用这两个类中的任何一个,可能会更好。

能否提供一些示例,说明您在函数中需要什么?例如:
double:Int=>Int,double(5)==10
对于这个特定的函数,我确实有一个版本可以按照我想要的方式工作:def removeFirst(obj:Any,list:list[Any]):list[Any={if(list isEmpty)Nil else{val fin:list[Any]=list.head match{case headAsList:list[Any=>if(containswithnestedlist)(obj,headAsList)removeFirst(obj,headAsList)::list.tail-else-headAsList::removeFirst(obj,list.tail)case}>if(list.head==obj)list.tail-else-list.head::removeFirst(obj,list.tail)}fin如果您测试一些示例,您可能会得到什么..对于注释中的多行代码,我礼貌地建议使用…I intential作为输出,这比我能解释的要好。但我遇到的主要问题是保持结构完整(使用泛型,而不是
Any
)。该函数可以删除元素的最后一次出现、所有出现、第N次出现、删除第N级列表上的所有元素、将元素添加到第N级列表等。编辑:对不起,代码是新的:)工作函数的代码谢谢您的回答,基本上,这不能用纯函数的方式完成(它需要类),但我必须承认,对于用其他函数式语言很容易完成的事情来说,它似乎太复杂和不雅观了。你指的是哪种函数式语言?我选择不让它更干净,因为我不想定义自己的树类型,但我可以很容易地做到这一点。这在任何其他不允许如上所述的递归类型定义的函数式语言中都不会有太大的不同。您也错了:这是纯函数代码。我在这里使用的类只是一个简单的数据类型。对不起,是的,我把我的意思弄错了。我的意思是,它(可能)不能完全用Scala提供的
列表
数据类型来完成,需要更改类型,而不是函数。至于哪种函数式语言,我首先要说的是Common Lisp(在这种语言中,对列表的操作是最简单的),但我也能在Prolog(不是真正的函数式编程语言)和Haskell中解决这类问题。你可以在Scala中使用任何一种。在Haskell中,我希望它非常类似,您会为它定义一个递归数据类型,不是吗?如果你只是通过嵌套来定义它,那么在Haskell中你会得到几乎相同的结果。不管怎样,我真的看不出这是一个常见的问题。如果是,则会有一个嵌套的列表数据类型。建造起来很容易,对所有人来说都是如此。问题不在于构建新的数据类型,我只是认为可以在Scala和泛型中使用基本的
List
数据类型来解决这类问题,但我想这必须在任何情况下完成。谢谢你的帮助。