Стандартная
partition делит коллекцию на две части, но обе остаются одного типа. Если нужно одновременно отфильтровать и преобразовать элементы — приходилось делать два прохода или писать свою функцию.partitionWith принимает функцию-разделитель с типом 'T -> Choice<'T1, 'T2> и возвращает два списка, которые могут иметь разные типы элементов:val inline partitionWith:
partitioner: ('T -> Choice<'T1, 'T2>) -> list: 'T list -> 'T1 list * 'T2 list
Удобно то, что total active pattern
(|A|B|) уже имеет сигнатуру 'T -> Choice<'T1, 'T2>, поэтому его можно передать напрямую:let (|Valid|Invalid|) (s: string) =
match System.Int32.TryParse s with
| true, n -> Valid n
| _ -> Invalid s
let parsed, errors =
["42"; "hello"; "7"; "oops"; "99"]
|> List.partitionWith (|Valid|Invalid|)
// parsed = [42; 7; 99]
// errors = ["hello"; "oops"]
За один проход получаем распарсенные числа и строки с ошибками — каждая в своём типе.
Функция доступна для
Array, List, Set и Array.Parallel.📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#sharp_view