сравнивая длину подсписков в списке F # - PullRequest
0 голосов
/ 07 октября 2018

Я новичок в F # и в настоящее время работаю над проблемой, в которой я пытаюсь сравнить длину подсписков внутри списка и возвращаю логическое значение.

Программа также должна возвращать значение «false», если какой-либо из подсписков пуст.Однако, поскольку я прогрессировал, я не смог решить мою текущую проблему, хотя я каким-то образом вижу, что не так (это связано с моим опытом в языке F # до сих пор).Надеюсь, кто-то может мне помочь, чтобы я мог быстро перейти к следующему проекту.

Моя программа на данный момент выглядит следующим образом:

let projectOne (initList: int list list) =
let mutable lst = initList.[0].Length
let mutable lst1 = ""
let n = initList.Length
for i=1 to n-1 do
    if lst = 0 || initList.[i].Length = 0 then
        lst1 <- "false"
    elif lst <> initList.[i].Length then
        lst1 <- "false"
    elif
        lst = initList.[i].Length then 
        lst1 <- "true"
lst1

printfn "The sublists are of same lenght: %A" (projectOne [[1;2;3;4];[4;5;6];[6;7;8;9];[5;6;7;8]])

Я так понимаю, чтопрямо сейчас я сравниваю [0] с увеличением [i] с каждой итерацией в моем цикле, это вызывает проблему, как в примере с печатью, я заканчиваю свои итерации, сравнивая [0] с [3], и так как 2 подсписка имеютПри одинаковом размере моя функция возвращает «true», что, очевидно, неверно, поскольку [1] имеет длину, меньшую, чем у остальных, поэтому результат должен быть «false».

Я пытался решить эту проблему, изменяязначение lst для каждой итерации, но это опять-таки вызывает проблему, если, например, [2] и [3] имеют одинаковую длину, а [0] и [1] - нет, и снова возвращает «true», даже если выходные данные должныбыть "ложным".(как [[1; 2; 3]; [3; 4; 5]; [6; 7]; [8; 9]])

Я не могу обернуть голову вокруг того, что япропустил.Поскольку я не могу разорвать цикл в F # (по крайней мере, не традиционным способом, как в Python), мне нужно выполнить все мои итерации, но я хочу, чтобы каждая итерация сравнивалась со средним значением всех предыдущих длин подсписков (если это имеет смысл).

Чего мне не хватает?:-) Я хотя и использовал оператор af List.fold для решения проблемы, но не уверен, как я собираюсь реализовать это, с тем фактом, что программе также нужно проверять наличие пустых списков.

IОднако могу сказать, что я пытаюсь решить проблему, используя метод, соответствующий моему уровню опыта.Я уверен, что доступно несколько очень компактных решений с использованием оператора конвейера |>, но я пока не могу использовать эти решения, поэтому я ищу более простое решение для начинающих perhabs.

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 08 октября 2018

Вот еще один дубль:

let projectOne lst =
    match lst with
    | h::t -> t |> List.forall(fun (l:_ list) -> l.Length = h.Length)
    | _    -> true
0 голосов
/ 08 октября 2018

Простым исправлением вашего кода может быть:

let projectOne (initList: int list list) =
    let length = initList.[0].Length
    let mutable result = length <> 0
    let n = initList.Length

    for i=1 to n-1 do
        result <- result && initList.[i].Length = length

    result

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


Другое, более функциональное, решение могло бы быть:

let haveEqualLength lists =
    let length = lists |> List.head |> List.length
    length <> 0 && lists |> List.tail |> List.tryFind (fun l -> l.Length <> length) = None
0 голосов
/ 07 октября 2018

Более функциональный способ думать об этом:

  1. Если все подсписки пусты, все они имеют одинаковую длину
  2. В противном случае, если подсписки пустыони не имеют одинаковую длину
  3. В противном случае списки имеют одинаковую длину, если их хвосты имеют одинаковую длину

Например:

let rec projectOne initList =
    if List.forall List.isEmpty initList then
        true
    else if List.exists List.isEmpty initList then
        false
    else
        projectOne (List.map List.tail initList)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...