How to convert array [Node] to NodeSeq?

I am trying to integrate a Lift application into some existing Java code. In one of my snippets, I have an array of Java objects that I need to map to NodeSeq. I can get an array of Node, but not NodeSeq. (At least not very functional looking).

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 

What is the cleanest way to do this?

+6
scala lift
source share
3 answers

I would simply convert the map output to a sequence (given that Seq[Node] is a superclass of NodeSeq )

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

or use foldLeft instead of map

 scala> def foo: NodeSeq = (Seq[Node]() /: data) {(seq, node)=> seq ++ <x>{node}</x>} foo: scala.xml.NodeSeq 
+8
source share
 scala> import collection.breakOut import collection.breakOut scala> def foo: NodeSeq = data.map { s => <x>{s}</x> }(breakOut) foo: scala.xml.NodeSeq 

There are actually two argument lists on the method map. The first accepts the function that you passed. The second accepts a CanBuildFrom object, which is used to create a builder, which then creates the return sequence. This argument is implicit, so usually the compiler populates it for you. It accepts 3 types of parameters: From, T, To. There are several preliminary restrictions (including in the NodeSeq object), but none of them correspond to From = Array, T = Node, To = NodeSeq.

breakOut solves this: it is a general method that returns an instance of CanBuildFrom by searching for the implicit CanBuildFrom [Nothing, T, To]. According to implicit search rules, any CanBuildFrom that matches T, To and has From> Nothing is acceptable. In this case: canBuildFrom in an Array object

+9
source share

You are looking for this method for a companion NodeSeq object.

 NodeSeq.fromSeq(s: Seq[Node]) 
+1
source share

All Articles