Here's one solution:

1
2
3
4
5
6
7
let tuplesOk arr =
  let candidates = Array.filter (fun (x,_) -> x > 1) arr
  (* take the last 3 elements for comparison *)
  let arr' = candidates.[candidates.Length-4 ..]
  (* is this new array sorted? *)
  arr' = Array.sortBy (fun (_,x) -> x) arr'
By on 12/25/2009 11:29 AM ()

Hello, KVB:
Thank you very much for your quick yet great reply.
I tried to trace the code.
I can see the array 'candidate' is an array with 3 tuples; but I can not see the array arr'. So, I changed your code, so it looks like:
let

tuplesOk arr =
let

candidates = Array.filter (fun

(x,_) -> x > 1) arr
(*

take the last 3 elements for comparison *)
let

arr' = candidates.[candidates.Length-3 ..]
(*

is this new array sorted? *)
arr' = Array.sortBy (fun

(_,x) -> x) arr'It works with my sample data.
Can you explain a little bit about your code?
But I can not see what is arr'.
And I don't quite understand Array.sortBy (fun

(_,x) -> x) arr'
Is it sort the array by the second element of each tuple?
Thanks!
Wish you have a Merry Christmas and a Happy New Year!

By on 12/25/2009 12:24 PM ()

Hi,

Sorry about the 3->4 typo; your fix is correct. To answer your other questions, arr' is a new array containing the last 3 elements of the candidate array. The Array.sortBy expression is then returning a new sorted version of this array sorted by the second element, as you guessed. In fact, you can replace

1
(fun (_,x) -> x)

by the built-in function snd.

By on 12/25/2009 7:41 PM ()

Hello, KVB:
Thank you very much for you good explanation, and for you great solution. Now I understand much better.
But I forgot to ask yet another question: How I can check if the second elements of the last 3 tuples are in descending order.
I mean, for example:
let aTuples = [|(2, 2.5); (1, 2.4); (3, 2.3); (4, 2.1)|]
I guess the Array.SortBy is only for ascending order, may be I have to use Array.sortWith to check if the second element of the qualified tuples is in descending order, right?
Can you show me the code how I can do this?
Thanks, Have a nice holiday and Happy New Year to you!

By on 12/26/2009 4:04 AM ()

I don't think sort is the right function for your spec. you need some form of fold(in the standard FP style). It can also be achieved via the zip() variants.

below is my first attempt:

let aTuples = [|(2, 2.1); (1, 2.2); (3, 2.3); (4, 2.5)|]

let l3 l = List.foldBack (fun (x,y) (flag, last, cnt) -> if x < 2 then (flag, last, cnt) else (flag && last >= y, (if cnt >=3 then float.MaxValue else y), cnt+1)) l (true, float.MaxValue, 0)

By on 12/26/2009 3:24 PM ()

Hello, Gary:
Thank you for your reply. But I think I have found another way.

let

aTuples = [|(2, 2.5); (1, 2.4); (3, 2.3); (4, 2.1)|]
let

tuplesOk arr =
let

candidates = Array.filter (fun

(x,_) -> x > 1) arr
(*

take the last 3 elements for comparison *)
let

arr' = candidates.[candidates.Length-3 ..]
(*

is this new array reversely sorted? *)
arr' = Array.rev(Array.sortBy (snd) arr')

if tuplesOk aTuples then printfn "in descending order!"

I think the logic is easier, as Array.foldBack is not easy to figure out.
My logic here is: if it is in descending order, then if I reverse the order of the array, then it must be in ascending order.
At least it works with my sample data and some other samples.
But thanks any way!

By on 12/26/2009 3:52 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