Как связать массив [узел] на NodeSeq?
Вопрос
Я пытаюсь интегрировать приложение для лифта в какой-то существующий код Java. В одном из моих фрагментов у меня есть массив объектов Java, которые мне нужно сопоставить это в odeseq. Я могу получить массив узла, но не odeseq. (По крайней мере, не в очень функциональном пути).
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
Какой самый чистый способ сделать это?
Решение
Я бы просто конвертировал 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
Другие советы
scala> import collection.breakOut
import collection.breakOut
scala> def foo: NodeSeq = data.map { s => <x>{s}</x> }(breakOut)
foo: scala.xml.NodeSeq
Карта метода на самом деле имеет два списка аргументов. Первый принимает функцию, которая вы прошли. Второй принимает объект CANBUILDFROM, который используется для создания строителя, который затем создает последовательность возврата. Этот аргумент неявный, поэтому обычно компилятор наполняет его для вас. Принимает 3 параметра типа: от, T, чтобы. Существует несколько пятен (в том числе в объекте nodeseq), но ни один из них не совпадает с = Array, T = узел, к = NodeSeq.
Breakout решает это: это универсальный метод, который возвращает экземпляр CANBUILDFROM, поиск неявных CanbuildSrom [ничего, t, to]. Согласно неявному правилам поиска, любой CanbuildFrom, который соответствует T, до и имеет от> ничего допустимого. В этом случае: CanbuildFrom в массиве объекта
Вы ищете этот метод на объекте компаньона Nodeseq.
NodeSeq.fromSeq(s: Seq[Node])