Wie kann ich Array [Knoten] zu NodeSeq konvertieren?
Frage
Ich versuche, einen Aufzug Anwendung in einen vorhandenen Java-Code zu integrieren. In einem meinem Schnipsel, ich habe ein Array von Java-Objekten, dass ich das in eine NodeSeq zur Karte benötigen. Ich kann ein Array von Knoten ist, aber kein NodeSeq. (Zumindest nicht in sehr funktional aussehenden Art und Weise).
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
Was ist der sauberste Weg, dies zu tun?
Lösung
Ich würde einfach map
Ausgabe Sequenz umwandeln (vorausgesetzt, dass Seq[Node]
eine Super-Klasse von NodeSeq
ist)
scala> def foo: NodeSeq = data.map { s => <x>{s}</x> } toSeq
foo: scala.xml.NodeSeq
oder Verwendung foldLeft
statt map
scala> def foo: NodeSeq = (Seq[Node]() /: data) {(seq, node)=> seq ++ <x>{node}</x>}
foo: scala.xml.NodeSeq
Andere Tipps
scala> import collection.breakOut
import collection.breakOut
scala> def foo: NodeSeq = data.map { s => <x>{s}</x> }(breakOut)
foo: scala.xml.NodeSeq
Die Methode Karte hat eigentlich zwei Argumentlisten. Die erste nimmt eine Funktion, die Sie übergeben. Die zweite akzeptiert ein CanBuildFrom Objekt, das verwendet wird, einen Builder zu erzeugen, die dann die zurückkehrende Sequenz aufbaut. Dieses Argument ist implizit, also in der Regel der Compiler füllt es für Sie. Er akzeptiert 3-Typ Parameter: Aus, T, To. Es gibt mehr PREDEF implicits (einschließlich in Objekt NodeSeq), aber keiner von ihnen übereinstimmt Von = Array, T = Knoten, To = NodeSeq.
breakout löst dieses Problem: Es ist eine generische Methode, dass die Rendite einer CanBuildFrom Instanz durch eine implizite CanBuildFrom Suche [Nichts, T, To]. Nach den impliziten Suchregeln, jede CanBuildFrom, die T, um Spiele und hat sich von> ist nichts akzeptabel. In diesem Fall: canBuildFrom in Objekt Array
Sie sind für diese Methode auf dem NodeSeq Begleitobjekt suchen.
NodeSeq.fromSeq(s: Seq[Node])