2011-04-26 81 views
2

我想通過一個數組並返回一個int值列表(索引值),當數組中的值匹配true時。Ocaml從遞歸函數中返回一個列表

該數組是一個真/假值的布爾數組。

let get_elements (i:int)(b:bool) : int = 
    if b = true then (i::l) 
    else (()) 
;; 

let rec true_list (b: bool array) : int list = 
    (fun i l -> get_elements i l) 
;; 

的語法是錯誤的我的代碼,我困惑於究竟是如何返回ints.I列表只想要回那些陣列中的真實元素的索引。

回答

3

您在get_elements中引用'l',但它不在該函數的範圍內。

下面是一個使用裁判的整數列表(一個可變的列表)的方法:

boolarray = [|true; false; true; false; false; true|] ;; 
type ilist = (int list) ref ;; 
let intlist() : ilist = ref [] ;; 
let push (l: ilist) (x: int) : unit = l := x::(!l) ;; 
let lst = intlist() ;; 
Array.iteri (fun i b -> if b = true then (push lst i)) boolarray ;; 
!lst ;; (* => int list = [5; 2; 0] *) 

或者,如果你寧願避免裁判(這通常是一個好主意),這是清潔:

let get_true_list (b: bool array) : int list = 
    let rec aux i lst =  
    if (i = Array.length b) then lst else 
     (if b.(i) = true then (aux (i+1) (i::lst)) else (aux (i+1) lst)) in 
    aux 0 [] ;; 
(* using boolarray defined above *) 
get_true_list boolarray ;; (* => int list = [5; 2; 0] *) 
+3

或用[電池](http://batteries.forge.ocamlcore.org/),'Array.fold_lefti(李樂趣IB - >若b的話,我::李李其他)[]' 。另外,我認爲在你的'ref'例子中,你應該真的把ref封裝在一個函數中,因爲在這裏它可能暗示ref始終是全局的,這比所需要的要難得多。 – gasche 2011-04-27 04:31:42

+0

我很高興你改變了你的答案,不涉及引用。 – nlucaroni 2011-04-27 14:54:23

2
 
I present an example which does not use state, avoids the 'if then else' construct making it easier to read and verify. 

let mylist = [| true; false; false; true; false; true |] in 
let get_true_indexes arr = 
    let a = Array.to_list arr in 
    let rec aux lst i acc = match lst with 
     | []     -> List.rev acc 
     | h::t when h = true -> aux t (i+1) (i::acc) 
     | h::t    -> aux t (i+1) acc 
    in 
    aux a 0 [] 
in 
get_true_indexes mylist