1
let standard = (0, 4.5M, 4L)
let tuples = [| ("A", -2, 1.0M, 2L); 
                ("B", -1, 2.0M, 3L); 
                ("C", 0, 3.0M, 4L); 
                ("D", 1, 4.0M, 5L); 
                ("E", 2, 5.0M, 6L) |]
let qualified = tuples
              |> Array.sortBy(fun (_, a, b, c) -> (a, -b, c))
              |> Array.filter(fun (_, a, b, c) -> (a, b, c) <= standard)
printfn "%A" qualified

我有一个元组数组和一个标准。我想对元组进行排序并挑选出符合要求的元组。
对于元组,我忽略了第一个元素,将第二个元素和第四个元素按普通方式排序,但也将第三个元素倒序排序;我有一个标准元组,因为所有具有第二个元素的元组至少与标准一样大,而第三个元素至多与标准一样大都是合格的元组。在上面的例子中,合格的元组是:= [| ("C", 0, 3.0M, 4L) |] 条件是:第二个元素>= 0 第三个元素<= 4.5M 第四个元素>= 4L 但是我的代码不起作用!让我知道如何编写一个函数可以完成这项工作!谢谢,周末愉快。约翰

4

2 回答 2

3

我认为没有任何聪明的方法可以使用适用于元组的内置比较来做你需要的事情。主要问题是比较将第一个元素视为最重要的元素,因此它决定仅使用前几个元素(甚至不考虑其余值。您的条件指定了对所有元素的限制。所以,Gustavo 的解决方案可能是最简单的方法。

但是,有一些小问题 - 首先,在排序之前执行过滤可能是个好主意,因为这样您的排序函数将需要对更少的元素进行排序:

 let qualified = 
   tuples 
   |> Array.sortBy (...) 
   |> Array.filter (...)

如果您想用某个易于更改的全局值来表示条件,那么创建一个包含 3 个值的元组来指定所需的最小值/最大值是不够的,因为您没有说该值是最小值还是最大值。 . 但是,您可以使用指定条件的函数元组:

let standard = ((fun _ -> true), (<=) 0, (>=) 4.5M, (<=) 4L) 

这指定第一个元素的所有值都可以,第二个元素的值应该大于零(代表一个接受和返回(<=) 0的函数)等等。然后你可以写:x0 <= x

let conditionsHold (p1, p2, p3, p4) (v1, v2, v3, v4) = 
  p1 v1 && p2 v2 && p3 v3 && p4 v4

let qualified = 
  tuples 
  |> Array.sortBy(fun (_, a, b, c) -> (a, -b, c)) 
  |> Array.filter (conditionsHold standard)
于 2011-12-04T17:24:28.247 回答
2

只需将最后一行更改为:

Array.filter(fun (_, a, b, c) -> let (x,y,z) = standard in a >= x && b <= y && c >= z)

请注意,元组 ("D", 1, 4.0M, 5L) 也符合条件。

更新:

Tomas 是对的,最好先过滤。另一种有趣的解决方法是使 3-uple 成为应用函子。

let pure' x = (x,x,x)
let (<*>) (f,g,h) (x,y,z) = (f x, g y, h z)

let standard = (0, 4.5M, 4L)
let tuples = [| ("A", -2, 1.0M, 2L); 
                ("B", -1, 2.0M, 3L); 
                ("C", 0, 3.0M, 4L); 
                ("D", 1, 4.0M, 5L); 
                ("E", 2, 5.0M, 6L) |]
let qualified = tuples              
              |> Array.filter(fun (_, a, b, c) -> ((>=),(<=),(>=)) <*> (a,b,c) <*> standard = pure' true)
              |> Array.sortBy(fun (_, a, b, c) -> (a, -b, c))
于 2011-12-04T17:07:11.003 回答