如何将 Array[Node] 转换为 NodeSeq?

发布于 2024-09-29 19:43:41 字数 517 浏览 4 评论 0原文

我正在尝试将 Lift 应用程序集成到一些现有的 Java 代码中。在我的一个片段中,我有一个 Java 对象数组,我需要将其映射到 NodeSeq 中。我可以获得 Node 数组,但不能获得 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

最干净的方法是什么?

I'm 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 that into a NodeSeq. I can get an Array of Node's, but not a NodeSeq. (At least, not in very functional-looking way).

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's the cleanest way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

谈场末日恋爱 2024-10-06 19:43:41
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[Nothing, T, To] 返回 CanBuildFrom 实例。根据隐式搜索规则,任何与 T、To 匹配且 From > 的 CanBuildFrom没有什么是可以接受的。在本例中:对象数组中的 canBuildFrom

scala> import collection.breakOut
import collection.breakOut

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

The method map actually has two argument lists. The first accepts a function, which you passed. The second accepts a CanBuildFrom object which is used to create a builder that then builds the returning sequence. This argument is implicit, so usually the compiler fills it for you. It accepts 3 type parameters: From, T, To. There are several predef implicits (including in object NodeSeq), but none of them matches From=Array, T=Node, To=NodeSeq.

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

情徒 2024-10-06 19:43:41

我只需将 map 输出转换为序列(假设 Seq[Node]NodeSeq 的超类)

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

或使用 foldLeft 而不是地图

scala> def foo: NodeSeq = (Seq[Node]() /: data) {(seq, node)=> seq ++ <x>{node}</x>}
foo: scala.xml.NodeSeq

I would simply convert map output to sequence (given that Seq[Node] is a super-class 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
残疾 2024-10-06 19:43:41

您正在 NodeSeq 伴随对象上寻找此方法。

NodeSeq.fromSeq(s: Seq[Node])

You are looking for this method on the NodeSeq companion object.

NodeSeq.fromSeq(s: Seq[Node])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文