2016-03-08 31 views
5

Câu hỏi này đến từ một người đang thực hiện chuyển đổi từ R sang F #. Tôi hoàn toàn thừa nhận cách tiếp cận của tôi ở đây có thể sai nên tôi đang tìm cách F # để làm điều này. Tôi có một tình huống mà tôi muốn lặp qua một tập hợp các tập tin XML, phân tích cú pháp chúng, và trích xuất một số giá trị để xác định những giá trị nào cần xử lý thêm. Độ nghiêng tự nhiên của tôi là Bản đồ trên mảng dữ liệu XML, exampleData trong trường hợp này, phân tích cú pháp từng loại bằng cách sử dụng nhà cung cấp loại RawDataProvider và cuối cùng tạo đối tượng Bản đồ cho mỗi tệp chứa XML được phân tích cú pháp, giá trị Trạng thái từ XML và ItemId giá trị.Loại bộ sưu tập F # cho các loại hỗn hợp

Chỉ ra rằng loại Bản đồ trong F # không giống như Danh sách trong R. Danh sách trong R về cơ bản là các hashmaps có thể hỗ trợ có các loại hỗn hợp. Dường như loại Bản đồ trong F # không hỗ trợ lưu trữ các loại hỗn hợp. Tôi đã tìm thấy điều này là vô cùng hữu ích trong công việc R của tôi và đang tìm kiếm những gì bộ sưu tập F # phù hợp cho việc này.

Hoặc, tôi có nghĩ về điều này không? Đây là một cách rất tự nhiên cho tôi để xử lý dữ liệu trong R vì vậy tôi mong đợi sẽ có một cách để làm điều đó trong F # là tốt. Giả thiết là tôi sẽ phân tích sâu hơn và thêm các phần tử dữ liệu bổ sung vào các bộ sưu tập này.

Cập nhật: Điều này có vẻ giống như một trường hợp sử dụng đơn giản như rằng phải có một cách thành ngữ để làm điều này trong F # mà không cần phải định nghĩa một kiểu ghi cho mỗi bước của phân tích. Tôi đã cập nhật ví dụ của mình để minh họa thêm những gì tôi đang cố gắng làm. Tôi muốn trở một mảng của các đối tượng đồ mà tôi đã phân tích:

type RawDataProvider = XmlProvider<"""<product Status="Good" ItemId="123" />""">   

let exampleData = [| """<product Status="Good" ItemId="123" />"""; """<product Status="Bad" ItemId="456" />"""; """<product Status="Good" ItemId="789" />"""|] 

let dataResult = 
      exampleData 
      |> Array.map(fun fileData -> RawDataProvider.Parse(fileData)) 
      |> Array.map(fun xml -> Map.empty.Add("xml", xml).Add("Status", xml.Status).Add("ItemId", xml.ItemId)) 
      |> Array.map(fun elem -> elem.["calc1Value"] = calc1 elem["itemId"]) 
      |> Array.map(fun elem -> elem.["calc2"] = calc2 elem.["ItemId"] elem.["calc1Value"]) 
+0

Không phải những gì bạn đã hỏi, nhưng tôi nghĩ 'File.ReadAllLines (file) |> Array.reduce (+)' có thể được thay thế bằng 'File.ReadAllText (file)' – CoderDennis

+0

@CoderDennis cảm ơn thông tin –

+0

Bạn nên sử dụng loại bản ghi thay vì băm được nhập sai. –

Trả lời

4

Đây là những gì tôi sẽ xem xét gần như thành ngữ ở đây - Tôi đang giữ hình dạng tương tự như ví dụ của bạn, do đó bạn có thể kết hợp hai:

let dataResult = 
    exampleData 
    |> Array.map(fun fileData -> RawDataProvider.Parse(fileData)) 
    |> Array.map(fun xml -> xml, calc1 xml.ItemId) 
    |> Array.map(fun (xml, calcedValue1) -> xml, calcedValue1, calc2 xml.ItemId calcedValue1) 

XmlProvider thực sự mang đến cho bạn không chỉ đơn giản là xml phân tích cú pháp, nhưng thực tế là nó tạo ra một đại diện mạnh mẽ gõ của xml. Điều này là tốt hơn so với việc đưa dữ liệu vào một bản đồ, trong đó nó cung cấp cho bạn đảm bảo mạnh mẽ hơn về việc liệu chương trình của bạn có đang làm đúng hay không. Ví dụ: nó sẽ không cho phép bạn trộn itemIdItemId vì nó đã xảy ra trong đoạn mã của bạn;)

Đối với các giá trị bạn tính toán trong các bước sau, bạn có thể sử dụng tuples thay vì bản ghi. Nói chung, các bản ghi được ưa thích hơn là các bộ dữ liệu khi chúng dẫn đến mã dễ đọc hơn, nhưng việc kết hợp các giá trị liên quan của các kiểu khác nhau vào các tập hợp đặc biệt thực sự là kịch bản khi sử dụng các bộ túp phát sáng.

Bây giờ, tôi đã nói gần thành ngữ - Tôi sẽ chia tay phân tích và xử lý phân tích cú pháp XMLs vào chức năng riêng biệt, và tính toán cả calc1calc2 kết quả trong một chức năng duy nhất thay vì sáng tác hai Array.maps như thế này:

let dataResult = 
    parsedData 
    |> Array.map(fun xml -> 
     let calced1 = calc1 xml.ItemId 
     xml, calced1, calc2 xml.ItemId calced1) 

Nếu bạn đến từ nền R, bạn có thể muốn xem Deedle để biết cách tiếp cận thay thế. Nó cung cấp cho bạn một quy trình làm việc tương tự như R trong F #.

Các vấn đề liên quan