【问题标题】:Check if a list and array are equal F#检查列表和数组是否相等 F#
【发布时间】:2021-01-20 00:42:34
【问题描述】:

我正在尝试比较一个列表和一个数组,看看它们是否相等。假设我们有一个列表list = [1;2;3;4] 和一个数组ar = [|1;2;3;4|]。如果相等,该函数应返回true,如果不相等,则应返回false。我是这样做的:

let list = [1;2;3;4]
let ar = [|1;2;3;4|]

let list' = Array.toList ar
(list = list')

所以基本上我所做的只是转换和比较两个列表。我的问题是有没有其他方法可以做到这一点,我的意思是不简单地在列表和数组之间转换,也不完全依赖库函数.

【问题讨论】:

    标签: arrays list f# compare


    【解决方案1】:

    您可以使用列表和数组(以及大多数其他集合)实现seq<'a> 接口(在.NET 术语中为IEnumerable<T>)这一事实,因此您可以将它们传递给来自@ 的函数987654323@ 模块没有任何转换。这只是使用一个接口,所以没有开销。

    我能想到的用于检查两个序列是否相同的最简单的函数是forall2,它接受两个序列并检查谓词是否成对地适用于元素。在这种情况下,谓词只是相等测试(fun a b -> a = b),您可以缩写为(=)

    let list = [1;2;3;4]
    let ar = [|1;2;3;4|]
    
    Seq.forall2 (=) list ar
    

    【讨论】:

    • 当两个序列的长度不同时,Seq.forall2 实际上并不能正确解决这个问题,因为它忽略了较长序列的额外元素。例如。如果list[1;2;3],则此解决方案仍将返回true,而应为false
    【解决方案2】:

    有很多方法可以做到这一点。这是一个成对比较元素的方法:

    if list.Length = ar.Length then
        Seq.zip list ar
            |> Seq.forall (fun (a, b) -> a = b)
    else false
    

    【讨论】:

    • 问题是关于标准库函数的。 Seq.compareWith 已经存在。
    【解决方案3】:

    F# docs说:

    您可以使用 Seq.compareWith 函数比较两个序列。该函数依次比较连续的元素,并在遇到第一个不等对时停止。任何其他元素都不会影响比较。

    在你的情况下变成单线:

    0 = Seq.compareWith (Comparer<_>.Default) list ar
    

    没有检查它是否编译。使用Comparer.Default 比较原语,否则,对于复杂的自定义类型,您可能需要提供自己的。

    【讨论】:

      【解决方案4】:

      使用 Linq;

      Enumerable.SequenceEqual (list, ar)
      

      【讨论】:

        【解决方案5】:

        基于this

        let l = [1;2;3;4]
        let a = [|1;2;3;4|]
        let result = Seq.compareWith Operators.compare l a
        

        【讨论】:

          猜你喜欢
          • 2016-09-13
          • 1970-01-01
          • 2020-02-12
          • 2012-01-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多