2017-06-07 93 views
0

我是新的reason/ocaml /函數式編程。追加到現有的列表/數組

我知道List.append[] @ []但這些函數將創建新的列表,但如何填充現有的列表/數組?

  1. 填充列表的最佳方式是什麼?
  2. 填充數組的最佳方式是什麼?意思是如果座標類型是let coords: array point = [];
  3. 或者這對於這種情況是錯誤的流程(算法)?

原因代碼:

type point = {x: int, y: int}; 

let coords: list point = []; 

let append raw => 
    Array.iter 
    (
     fun data => { 
     let p = {x: data.x, y: data.y}; 
     /* how to append p to coords */ 
     () 
     } 
    ) 
    raw; 

JS模擬:

const coords = []; 
const append = raw => raw.forEach({x, y} => { 
    coords.push({ 
    x: process(x), 
    y: process(y) 
    }); 
}); 
+0

令人討厭的簡單答案:在FP中,您不需要單獨的'coords',因爲它是'raw'的精確副本。只要繼續使用生。 – Yawar

+0

@Yawar我有更新的代碼。例如 - coords包含了處理過的xy(意思是不完全複製) – tuchk4

+0

看到Cheng Lou的回答,它很全面,但總之你會做一些像'List.map(fun {x,y} => {x:process x ,y:process y})raw' – Yawar

回答

6

歡迎的理由!

在Reason/OCaml中,列表是不可變的。在引擎蓋下他們是簡單的單鏈表。每次「修改」它們時都會創建新的。這裏有一個例子:

let a = [1, 2, 3]; 
let b = [0, ...a]; 

這類似於JavaScript的數組「蔓延」,但在這裏你採取現有a,在前面連接一個新的節點0,並呼籲過b。 a仍然指向[1, 2, 3](因此「不可變」)。 b現在是[0, 1, 2, 3]。這是有效的,因爲[1, 2, 3]部分是共享的。

這樣做的好處是,你不必擔心傳遞你的清單,並意外地有一個不起眼的功能修改它。 List的不變性允許你純粹通過查看你現在正在凝視的值來推理你的代碼(因爲它永遠不會改變!)。

列表的缺點是,它是沒有效率的,在末尾加上一句:

let c = a @ [4] 

那次行動基本上採取一個項目,[4]的列表,並先後在附着[1, 2, 3]每個項目給它。所以在perf中是線性的。但從清單實施的簡單性來看,歷史上認爲這是值得的權衡。

所以3.如果您嘗試設置列表項目,那是錯誤的流程。

  1. 來填充你的情況列表中的最佳方式是通過映射在它的非mutatively,從舊名單:let newList = List.map (fun blabla => ...) raw
  2. 相同的陣列。映射它。如果你曾經卡住過,那麼有Array.of_listArray.to_list

更多數組:OCaml數組是可變的,它的大小是不可改變的。把它看作是一塊記憶。您將通過Array.make newSize分配新陣列,然後通過Array.set填充它。如果你調整數組的大小,這是沒有意義的,所以選擇正確的數據結構。

對於JS編譯,BuckleScript將ocaml數組編譯爲JS數組。這是可變的可調整大小。您可以在Js.Array

下找到您熟悉的JS陣列操作。作爲一般啓發式,如果您想更改長度:請嘗試filter。如果您想更改長度和包含的項目,請嘗試fold_left。否則,map

最近,我們已經開始實現一些不可變,可調整大小,可選可變數組。敬請關注!

+0

'List.map(fun blabla => ...)raw' - 但在這種情況下,結果應分配給新變量,並根據提供的示例 - 範圍(在哪裏創建列表,以及列表應該在哪裏映射)是不同的。所以這樣的流量根據FP流量是不正確的? – tuchk4

+0

是的,我把它分配給一個新的變量。我已經添加了一個澄清。順便說一句,如果你不使用返回值,類型系統會警告你。所以一切都很好。 – chenglou

+0

與'Js.Array'一切都好,但我想盡可能地使用原因流程和結構。如何與這種情況下https://gist.github.com/tuchk4/7130405338a41a7a91b6de22356c072e主要問題,我認爲我不知道如何使用FP :) – tuchk4