#php #ocaml #partitioning
Вопрос:
Я обнаружил, что периодически переписываю эти (или аналогичные) функции. Интересно, есть ли у stdlib более идиоматическое решение? Как показано ниже, я решил использовать containers
библиотеку для некоторых функций, но подозреваю, что набор инструментов по умолчанию также может обладать достаточными, чистыми возможностями.
Для всех x в X удалите/разделите первое вхождение x из Y.
Ниже показана exn
реализация без ограничений.
Примеры:
extract [1] [2;1;3]
;; ([1], [], [2;3])
extract [2;4] [2;1;3;4]
;; ([2;4], [], [1;3])
extract [5] [1;2;3]
;; ([], [5], [1;2;3])
extract [1;1;9] [2;3;1;4;1;5;1]
;; ([1;1], [9], [2;3;4;5;1])
Допущения:
- X amp; Y и не правильные наборы, а связанные коллекции (например, список, массив)
- коллекции неупорядочены
Реализация:
(* Given needles and haystack lists, extract needles elements from haystack.
Produce (successfully_extracted, unsuccessfully_extracted, remaining_haystack) *)
let extract needles haystack =
let open CCList in
let f (extracted, needles', haystack') curr =
match find_idx (Int.equal curr) needles' with
| Some (idx, v) -> (v :: extracted, remove_at_idx idx needles', haystack')
| _ -> (extracted, needles', curr :: haystack')
in
fold_left f ([], needles, []) haystack |> fun (a, b, c) -> (a, b, rev c)
Комментарии:
1. Эта функция выглядит для меня очень специфичной и нишевой. И я никогда лично не реализовывал ничего близкого к этому, честно говоря. Поэтому меня не удивляет, что ничего подобного не существует ни в стандартной библиотеке, ни в ее расширениях, таких как Ядро или контейнеры. Можете ли вы поделиться своими историями пользователей? Например, когда и почему вам могут понадобиться такие селекторы, возможно, существует более естественный способ кодирования ваших проблем.
2. Конечно! Мне нужно вытащить иголки из стога сена. У меня есть ведро вещей (представляющих физические или виртуальные инвестиции), и я получаю заказ. Этот порядок вещей следует извлечь из инвентаря стога сена. В стоге сена может быть несколько копий чего-либо, например, на полке магазина есть N виджетов в инвентаре, а заказ запрашивает только N-1 виджетов, поэтому в следующем стоге сена останется 1 виджет. Возможно, чего-то нет в наличии-я хочу знать, какой заказ не может быть выполнен. Возможно, предпочтительнее преобразовать в тип карты, а затем обратно, но мои списки известны небольшими.
3. Не лучше ли было бы представлять доступность каждого виджета с помощью номера, а не дублировать его? Например, когда в моем магазине сто клавиатур, я бы, вероятно, представил их как один товар с наличием 100 наименований.
Ответ №1:
Эй, я не уверен, хорошо ли я понял твою проблему, но, может быть, это решит ее :
let rec pop popL l =
match popL with
| [] -> l
| e :: es -> begin
match l with
| x :: xs when x = e -> pop es xs
| x :: xs -> x :: pop popL xs
| [] -> []
end;;