Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.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
Scala Liftweb-将列表[Box[T]]转换为框[List[T]]_Scala_Lift_Scala Collections - Fatal编程技术网

Scala Liftweb-将列表[Box[T]]转换为框[List[T]]

Scala Liftweb-将列表[Box[T]]转换为框[List[T]],scala,lift,scala-collections,Scala,Lift,Scala Collections,我想将List[Box[T]]转换为Box[List[T]] 我知道我可以使用foldRight,但我找不到一种优雅的方式来使用它 编辑我想保留框的属性,也就是说,如果出现任何故障,请返回一个带有此故障的框。如果您只想收集“完整”值 我不确定您为什么想要一个框[List[T]],因为空的列表应该足以表示缺少任何值。我想这对你来说已经足够了 我手边没有Lift的副本,但我知道Box的灵感来自Option,并且有一个平面图方法,因此: 长格式: for { box <- list va

我想将
List[Box[T]]
转换为
Box[List[T]]

我知道我可以使用
foldRight
,但我找不到一种优雅的方式来使用它

编辑我想保留
框的属性
,也就是说,如果出现任何故障,请返回一个带有此故障的
框。

如果您只想收集“完整”值 我不确定您为什么想要一个框[List[T]],因为空的列表应该足以表示缺少任何值。我想这对你来说已经足够了

我手边没有Lift的副本,但我知道Box的灵感来自Option,并且有一个平面图方法,因此:

长格式:

for {
  box <- list
  value <- box
} yield value
最短形式:

list.flatten
如果您也想收集故障: 下面是我用来解决这类问题的
mapSplit
函数。您可以轻松地将其调整为使用
,而不是

/**
 * Splits the input list into a list of B's and a list of C's, depending on which type of value the mapper function returns.
 */
def mapSplit[A,B,C](in: Traversable[A])(mapper: (A) ⇒ Either[B,C]): (Seq[B], Seq[C]) = {
  @tailrec
  def mapSplit0(in: Traversable[A], bs: Vector[B], cs: Vector[C]): (Seq[B], Seq[C]) = {
    in match {
      case t if t.nonEmpty ⇒
        val a = t.head
        val as = t.tail
        mapper(a) match {
          case Left(b)  ⇒ mapSplit0(as, bs :+ b, cs     )
          case Right(c) ⇒ mapSplit0(as, bs,      cs :+ c)
        }
      case t ⇒
        (bs, cs)
    }
  }

  mapSplit0(in, Vector[B](), Vector[C]())
}
当我只想分割已经是Seq[a,B]]的东西时,我使用这个:

/**
 * Splits a List[Either[A,B]] into a List[A] from the lefts and a List[B] from the   rights.
 * A degenerate form of {@link #mapSplit}.
 */
def splitEither[A,B](in: Traversable[Either[A,B]]): (Seq[A], Seq[B]) = mapSplit(in)(identity)
如果您只想收集“完整”值 我不确定您为什么想要一个框[List[T]],因为空的列表应该足以表示缺少任何值。我想这对你来说已经足够了

我手边没有Lift的副本,但我知道Box的灵感来自Option,并且有一个平面图方法,因此:

长格式:

for {
  box <- list
  value <- box
} yield value
最短形式:

list.flatten
如果您也想收集故障: 下面是我用来解决这类问题的
mapSplit
函数。您可以轻松地将其调整为使用
,而不是

/**
 * Splits the input list into a list of B's and a list of C's, depending on which type of value the mapper function returns.
 */
def mapSplit[A,B,C](in: Traversable[A])(mapper: (A) ⇒ Either[B,C]): (Seq[B], Seq[C]) = {
  @tailrec
  def mapSplit0(in: Traversable[A], bs: Vector[B], cs: Vector[C]): (Seq[B], Seq[C]) = {
    in match {
      case t if t.nonEmpty ⇒
        val a = t.head
        val as = t.tail
        mapper(a) match {
          case Left(b)  ⇒ mapSplit0(as, bs :+ b, cs     )
          case Right(c) ⇒ mapSplit0(as, bs,      cs :+ c)
        }
      case t ⇒
        (bs, cs)
    }
  }

  mapSplit0(in, Vector[B](), Vector[C]())
}
当我只想分割已经是Seq[a,B]]的东西时,我使用这个:

/**
 * Splits a List[Either[A,B]] into a List[A] from the lefts and a List[B] from the   rights.
 * A degenerate form of {@link #mapSplit}.
 */
def splitEither[A,B](in: Traversable[Either[A,B]]): (Seq[A], Seq[B]) = mapSplit(in)(identity)

使用尾部递归函数比使用折叠函数更容易:

final def flip[T](l: List[Option[T]], found: List[T] = Nil): Option[List[T]] = l match {
  case Nil => if (found.isEmpty) None else Some(found.reverse)
  case None :: rest => None
  case Some(x) :: rest => flip(rest, x :: found)
}
这与预期的效果一样:

scala> flip(List(Some(3),Some(5),Some(2)))
res3: Option[List[Int]] = Some(List(3, 5, 2))

scala> flip(List(Some(1),None,Some(-1)))
res4: Option[List[Int]] = None
我们也可以使用
Iterator.iterate
,但这样做更麻烦,速度也更慢,所以在这种情况下我会避免使用这种方法


(另请参见我在问题4e6中的答案。)

使用尾部递归函数比使用折叠函数更容易做到这一点:

final def flip[T](l: List[Option[T]], found: List[T] = Nil): Option[List[T]] = l match {
  case Nil => if (found.isEmpty) None else Some(found.reverse)
  case None :: rest => None
  case Some(x) :: rest => flip(rest, x :: found)
}
这与预期的效果一样:

scala> flip(List(Some(3),Some(5),Some(2)))
res3: Option[List[Int]] = Some(List(3, 5, 2))

scala> flip(List(Some(1),None,Some(-1)))
res4: Option[List[Int]] = None
我们也可以使用
Iterator.iterate
,但这样做更麻烦,速度也更慢,所以在这种情况下我会避免使用这种方法


(另请参见我在问题4e6中的答案。)

希望这是他想要的……还有“如果有
None
,列表是
None
”版本。可能是这样,但foldRight通常不用于提前终止。@AlexCruise如果有故障,我希望保留这些故障。也就是说,如果列表中有一个失败对象,我想返回那个对象。在您的结果中,
EmptyBox
对象被忽略了,我想。希望这是他想要的……还有“如果有
None
,列表是
None
”版本。可能是这样,但是foldRight通常不用于提前终止。@如果有,我希望保留失败。也就是说,如果列表中有一个失败对象,我想返回那个对象。在您的结果中,
EmptyBox
对象被忽略。类似的,它在同一个头脑中,但您无法链接选项,我不希望使用Scalaz。类似的,它在同一个头脑中,但您无法链接选项,我不希望使用Scalaz。