При написании кода в функциональном стиле вы часто будете использовать рекурсию, если не явно, то неявно, поскольку большинство функций списка / массива / последовательности используют рекурсию под капотом.
В F # вам необходимо явно указатьчто функция является рекурсивной, поэтому созданная вами функция будет использовать синтаксис let rec
в своем определении.Учитывая ваши требования, ваша функция, вероятно, будет выглядеть следующим образом:
let rec myFilter (name: string) (input: (string * string * int) list) =
...
Для этого класса задач, когда вы рекурсивно перебираете список, вы обычно используете сопоставление с образцом, чтобы проверить, находитесь ли вы в концеlist, и если да, вернуть пустой список.
let rec myFilter (name: string) (input: (string * string * int) list) =
match input with
| [] -> []
...
Теперь вам нужно написать сопоставление с шаблоном, которое проверяет первый элемент в кортеже на соответствие предоставленному имени.Вы можете использовать сопоставление с образцом в начале списка и синтаксис F # * when
, чтобы деконструировать заголовок списка для сравнения
let rec myFilter (name: string) (input: (string * string * int) list) =
match input with
| [] -> []
| ((a, b, _) :: rest) when a = name -> b :: myFilter name rest
...
Этот второй случай совпадает, когда a
соответствует запрашиваемому имени.Когда он совпадет, он вернет новый список, в котором b
является главой списка, а затем возьмет оставшуюся часть списка кортежей и рекурсивно вызовет myFilter
.Вот как вы рекурсивно перебираете список.
У нас есть еще один случай для проверки: если мы не найдем совпадения, мы хотим продолжать проходить по списку, не собирая b
.Это можно выразить, откинув голову и рекурсивно позвонив myFilter
, отправив только остальные наборы.
let rec myFilter (name: string) (input: (string * string * int) list) =
match input with
| [] -> []
| ((a, b, _) :: rest) when a = name -> b :: myFilter name rest
| (_ :: rest) -> myFilter name rest
Позвонив на myFilter "a" [("a","x",3);("b","y",4);("a","z",5)]
, вы получите ["x"; "z"]
, как и ожидалось.