From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from weis@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id KAA04607 for caml-redistribution; Thu, 17 Jul 1997 10:45:03 +0200 (MET DST) Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id VAA24903 for ; Wed, 16 Jul 1997 21:29:07 +0200 (MET DST) Received: from dwarin.oit.umass.edu (freya.cs.umass.edu [128.119.40.195]) by nez-perce.inria.fr (8.8.5/8.7.3) with ESMTP id VAA04954 for ; Wed, 16 Jul 1997 21:29:00 +0200 (MET DST) Received: (from ajenkins@localhost) by dwarin.oit.umass.edu (8.8.5/8.8.5) id PAA00882; Wed, 16 Jul 1997 15:27:40 -0400 Date: Wed, 16 Jul 1997 15:27:40 -0400 Message-Id: <199707161927.PAA00882@dwarin.oit.umass.edu> From: "Adam P. Jenkins" To: caml-list@inria.fr Subject: mapi, iteri, fold_lefti, fold_righti Sender: weis Hi, I find a lot of times that Array.map and Array.iter aren't adequate when I want to iterate through an array, since I need to use the corresponding indexes as well. While it's trivial to do what I need with a for loop, I like having a function. I've therefore written my own mapi and iteri, like SML's mapi and appi. For those not familiar with SML, iteri is like Array.iter except f is called with the index of the element as well as the element. Also, I think Array should have fold functions too, so I wrote fold_left, fold_right, fold_lefti, and fold_righti for arrays. In my opinion these belong in the Array module for O'Caml, but maybe others don't find they use these as much as me. Here they are. Cheers, Adam -- Adam P. Jenkins mailto:ajenkins@cs.umass.edu module MyArray : sig (* mapi and iteri are like map and iter except f is called with the element's index and the element as arguments. *) val iteri : (int -> 'a -> 'b) -> 'a array -> unit val mapi : (int -> 'a -> 'b) -> 'a array -> 'b array (* fold_left and fold_right for arrays, just like the list versions *) val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b array -> 'a val fold_right : ('a -> 'b -> 'b) -> 'a array -> 'b -> 'b (* the same as fold_left and fold_right, except f gets the element's index as argument too. *) val fold_lefti : (int -> 'a -> 'b -> 'a) -> 'a -> 'b array -> 'a val fold_righti : (int -> 'a -> 'b -> 'b) -> 'a array -> 'b -> 'b end = struct let iteri f a = for i = 0 to (Array.length a) - 1 do f i a.(i) done let mapi f a = let len = Array.length a in if len = 0 then [||] else begin let newa = Array.create len a.(0) in for i = 0 to len - 1 do newa.(i) <- f i a.(i) done; newa end let fold_left f init a = let len = Array.length a in if len = 0 then init else begin let accum = ref init in for i = 0 to len - 1 do accum := f !accum a.(i) done; !accum end let fold_right f a init = let len = Array.length a in if len = 0 then init else begin let accum = ref init in for i = len - 1 downto 0 do accum := f a.(i) !accum done; !accum end let fold_lefti f init a = let len = Array.length a in if len = 0 then init else begin let accum = ref init in for i = 0 to len - 1 do accum := f i !accum a.(i) done; !accum end let fold_righti f a init = let len = Array.length a in if len = 0 then init else begin let accum = ref init in for i = len - 1 downto 0 do accum := f i a.(i) !accum done; !accum end end