Проверить, равны ли список и массив F #

Jan 20 2021

Я пытаюсь сравнить список и массив и посмотреть, равны ли они. Допустим, у нас есть список 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')

Итак, в основном то, что я делаю, - это просто конвертирую и сравниваю два списка. Мой вопрос: есть ли другой способ сделать это, я имею в виду, который не просто конвертирует между списком и массивом и который не полностью полагается на библиотечные функции.

Ответы

4 TomasPetricek Jan 20 2021 at 19:09

Вы можете использовать тот факт, что и списки, и массивы (а также большинство других коллекций) реализуют seq<'a>интерфейс ( IEnumerable<T>в терминах .NET), и поэтому вы можете просто передавать их функциям из Seqмодуля без каких-либо преобразований. Это просто использование интерфейса, поэтому нет накладных расходов.

Самая простая функция, которую я могу придумать для проверки идентичности двух последовательностей, - forall2это две последовательности и проверка того, что предикат выполняется для попарных элементов. В этом случае предикат - это просто проверка на равенство, (fun a b -> a = b)которую вы можете сократить как (=):

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

Seq.forall2 (=) list ar
2 brianberns Jan 20 2021 at 10:37

Есть много способов сделать это. Вот тот, который сравнивает элементы попарно:

if list.Length = ar.Length then
    Seq.zip list ar
        |> Seq.forall (fun (a, b) -> a = b)
else false
2 SerejaBogolubov Jan 20 2021 at 15:01

Документы F # говорят:

Вы сравниваете две последовательности с помощью функции Seq.compareWith. Функция по очереди сравнивает последовательные элементы и останавливается, когда встречает первую неравную пару. Никакие дополнительные элементы не участвуют в сравнении.

Которая в вашем случае становится одной строчкой:

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

Не проверял, компилируется. Используйте Comparer.Default для сравнения примитивов, в противном случае для сложных настраиваемых типов вам может потребоваться предоставить свои собственные.

2 sardok Jan 20 2021 at 19:12

С помощью Linq;

Enumerable.SequenceEqual (list, ar)
2 ThanasisK Jan 20 2021 at 19:24

На основании этого

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