Как конвертировать массив [Node] в NodeSeq? - PullRequest
7 голосов
/ 29 октября 2010

Я пытаюсь интегрировать приложение Lift в некоторый существующий код Java. В одном из моих фрагментов у меня есть массив объектов Java, который мне необходим для отображения этого в NodeSeq. Я могу получить массив узлов, но не NodeSeq. (По крайней мере, не очень функционально).

import scala.xml.NodeSeq

// pretend this is code I can't do anything about
val data = Array("one", "two", "three")

// this is the function I need to write
def foo: NodeSeq = data.map { s => <x>{s}</x> }
//                          ^
// error: type mismatch;
//  found   : Array[scala.xml.Elem]
//  required: scala.xml.NodeSeq

Какой самый чистый способ сделать это?

Ответы [ 3 ]

10 голосов
/ 29 октября 2010
scala> import collection.breakOut
import collection.breakOut

scala> def foo: NodeSeq = data.map { s => <x>{s}</x> }(breakOut)
foo: scala.xml.NodeSeq

Карта методов на самом деле имеет два списка аргументов.Первый принимает функцию, которую вы передали.Второй принимает объект CanBuildFrom, который используется для создания компоновщика, который затем строит возвращаемую последовательность.Этот аргумент неявный, поэтому обычно компилятор заполняет его для вас.Он принимает 3 параметра типа: From, T, To.Существует несколько предопределенных последствий (в том числе в объекте NodeSeq), но ни один из них не соответствует From = Array, T = Node, To = NodeSeq.

breakOut решает эту проблему: это универсальный метод, который возвращает экземпляр CanBuildFrom путемпоиск неявного CanBuildFrom [Nothing, T, To].Согласно неявным правилам поиска, любой CanBuildFrom, который соответствует T, To и имеет From> Nothing, является приемлемым.В этом случае: canBuildFrom в объекте Array

8 голосов
/ 29 октября 2010

Я бы просто преобразовал вывод map в последовательность (учитывая, что Seq[Node] - это суперкласс NodeSeq)

scala> def foo: NodeSeq = data.map { s => <x>{s}</x> } toSeq
foo: scala.xml.NodeSeq

или используйте foldLeft вместо map

scala> def foo: NodeSeq = (Seq[Node]() /: data) {(seq, node)=> seq ++ <x>{node}</x>}
foo: scala.xml.NodeSeq
2 голосов
/ 09 марта 2015

Вы ищете этот метод для объекта-компаньона NodeSeq.

NodeSeq.fromSeq(s: Seq[Node])
...