Hi KarlTi,

Here is a purely functional piece of code to do what I think you are looking for. I think your second post wasn't doing the "Then i want to split that array..." part. The code below does just that, in fact it skips the intermediate step of getting the list of indexes altogether. Sometimes thinking what you would do imperatively is counter-productive when programming functionally. In this case trying to create an intermediate list of indexes makes the functional solution harder and less efficient.

1
2
3
4
5
6
7
8
9
let f p xs = 
  let f xs = 
    match xs with
    | [] -> None
    | x::xs' -> let ys, zs = break p xs'
                Some (x::ys, zs)
  unfold f xs

let result = f (fun (x : string) -> x.StartsWith("#Date:")) logfile

This code uses lists and the following general-purpose helper functions. You could do the same thing with sequences, but it is harder and less educational about (pure) functional programming.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let unfold f x =
  let rec unfold' x acc =
    match f x with
    | None -> List.rev acc
    | Some (a, x') -> unfold' x' (a::acc)
  unfold' x []
    
let break p xs = 
  let rec break' xs acc =
    match xs with
    | [] -> List.rev acc, []
    | x::_ when p x -> List.rev acc, xs
    | x::xs' -> break' xs' (x::acc)
  break' xs []
By on 6/3/2008 7:16 AM ()

OK, I tried several things & what i can come up with is the code sequence below.
I use a ref that i thread through Seq.choose. Looks not too elegant, but nevertheless...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#light

open System
open System.IO
open System.Text

let logfile =
    seq { use reader = new StreamReader(File.OpenRead(@"C:\Karl\YALP\ex080508.log"))
          while not reader.EndOfStream do             yield reader.ReadLine() }

let i = ref 0
let r =
    logfile |>
    Seq.choose
        (fun x ->
             incr i
             let y = String.split [' '] x 
             let z = List.hd y
             if z = "#Date:" then 
                Some ((sprintf "%d" !i)::y)
             else
                None)

Looks not quite right for me...
Especially the sprintf & the incr.

Maybe someone can point me to the right direction....

Thank you & enjoy your weekend!

- Karl

By on 5/31/2008 12:00 PM ()

I haven't looked at your problem very closely, but i would probably annotate each line in the sequence with the index of the line:

1
let logfile' = Seq.mapi (fun idx line -> (idx, line)) logfile

and then filter the tuple sequence based on the contents of the lines.

By on 5/31/2008 5:02 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper