Обновление: Я создал запрос UserVoice для этого: Expand on the Cardinality functions for Seq.Non-throwing версия Seq.exactlyOne для проверки последовательности однократных сигналов
Мне нужна функциональность Seq.exactlyOne
, но с семантикой Some/None. Другими словами, мне нужен либо Seq.head
, либо, если последовательность пуста или содержит более одного элемента, мне ничего не нужно. Использование Seq.exactlyOne
будет забрасывать в таких случаях.
Я не думаю, что есть встроенный способ получить это (хотя это звучит так тривиально, что можно было бы ожидать, что есть аналог для Seq.singleton
). Я придумал это, но он чувствует себя запутанным:
let trySingleton sq =
match Seq.isEmpty sq with
| true -> None
| false ->
match sq |> Seq.indexed |> Seq.tryFind (fst >> ((=) 1)) with
| Some _ -> None
| None -> Seq.exactlyOne sq |> Some
Дает:
> trySingleton [|1;2;3|];;
val it : int option = None
> trySingleton Seq.empty<int>;;
val it : int option = None
> trySingleton [|1|];;
val it : int option = Some 1
Есть более простой, или даже встроенный в путь? Я мог бы попробовать/поймать на Seq.exactlyOne
, но это построение бизнес-логики вокруг исключений, я бы предпочел (и это дорого).
UPDATE: я не был осведомлен о функции Seq.tryItem
, что бы сделать это проще:
let trySingleton sq =
match sq |> Seq.tryItem 1 with
| Some _ -> None
| None -> Seq.tryHead sq
(лучше, но он по-прежнему чувствует себя довольно неловко)
Кстати, вы можете предложите 'tryExactlyOne' в качестве дополнения к языку: https://fslang.uservoice.com/forums/245727-f-language Я бы добавил предложение сам, но у меня нет голосов на этом форуме. –
@MarkSeemann: сделано, как [можно увидеть здесь] (https://fslang.uservoice.com/forums/245727-f-language/suggestions/16308904-expand-on-cardinality-functions-seq-exactlyone-wi) , tx для предложения. – Abel