2010-10-28 20 views
6

Tôi đang cố gắng tích hợp ứng dụng Nâng vào một số mã Java hiện có. Trong một trong các đoạn mã của tôi, tôi có một mảng các đối tượng Java mà tôi cần để ánh xạ nó thành một NodeSeq. Tôi có thể nhận được một mảng của Node, nhưng không phải là một NodeSeq. (Ít nhất, không theo cách nhìn rất chức năng).Làm cách nào để chuyển đổi Array [Node] thành 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 

Cách sạch nhất để thực hiện việc này là gì?

+1

Bạn luôn có sẵn phương thức '++' :-) 'new NodeSeq() ++ theArray_Elm_thing'. Có thể có những cách tốt hơn. Chúc mừng mã hóa. –

+1

NodeSeq là trừu tượng, do đó, 'NodeSeq mới()' không hoạt động. –

Trả lời

8

Tôi chỉ đơn giản là sẽ chuyển đổi map đầu ra để chụp liên tục (cho rằng Seq[Node] là một siêu lớp của NodeSeq)

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

hoặc sử dụng foldLeft thay vì map

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

toSeq là sự sang trọng mà tôi đang tìm kiếm. Cảm ơn! – leedm777

+0

Sử dụng bản đồ và sau đó làSeq nghĩa là bạn đang tạo 2 bộ sưu tập. Sử dụng breakOut bạn đang tạo 1. – IttayD

+2

'toSeq' tạo một trình bao bọc (http://www.scala-lang.org/api/current/scala/collection/mutable/WrappedArray.html), do đó, có một hình phạt hiệu suất khốn khổ. http://www.scala-lang.org/docu/files/collections-api/collections_38.html –

9
scala> import collection.breakOut 
import collection.breakOut 

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

Bản đồ phương pháp thực sự có hai danh sách đối số. Người đầu tiên chấp nhận một hàm mà bạn đã vượt qua. Thứ hai chấp nhận một đối tượng CanBuildFrom được sử dụng để tạo một trình xây dựng để xây dựng chuỗi trả về. Đối số này là ẩn, vì vậy thường trình biên dịch sẽ điền nó cho bạn. Nó chấp nhận 3 tham số kiểu: From, T, To. Có một số hàm ý predef (bao gồm trong đối tượng NodeSeq), nhưng không ai trong số chúng khớp với From = Array, T = Node, To = NodeSeq.

breakOut giải quyết vấn đề này: nó là một phương thức chung để trả về một thể hiện CanBuildFrom bằng cách tìm kiếm một CanBuildFrom ngầm định [Nothing, T, To]. Theo các quy tắc tìm kiếm tiềm ẩn, bất kỳ CanBuildFrom nào khớp với T, To và có From> Nothing is acceptable. Trong trường hợp này: canBuildFrom trong đối tượng Array

+2

Có vẻ như thích hợp để liên kết đến câu hỏi breakOut: http://stackoverflow.com/questions/1715681/scala-2-8-breakout –

1

Bạn đang tìm phương pháp này trên đối tượng đồng hành NodeSeq.

NodeSeq.fromSeq(s: Seq[Node])