Каков стандартный способ удаления элемента из списка в OCaml?

#ocaml

#ocaml

Вопрос:

В common lisp мы можем использовать remove функцию.

Кажется, в OCaml такого метода нет?

Комментарии:

1. Как именно должно выполняться удаление? Вы просто хотите filter сохранить список? ( remove , по крайней мере, в общепринятом смысле Lisp — это очень, очень страшный зверь … начальные / конечные диапазоны, количества, ключи и предикаты, о боже!)

Ответ №1:

Списки в OCaml неизменяемы. Таким образом, вы не можете удалять элементы из них. Обычно вы создаете другой список, в котором нет того, что вам не нужно. Для этого вы бы использовали List.filter .

Если вам абсолютно необходимо иметь изменяемые списки, вы можете. В Batteries есть нечто, называемое Dllist, которое может быть похоже на то, что вы хотите. (Однако это двусвязный список, в отличие от списка Lisp).

На мой взгляд, одна из замечательных особенностей OCaml заключается в том, что чисто функциональное подмножество действительно довольно эффективно. Мне никогда не приходилось использовать изменяемые списки в моих собственных проектах.

Комментарии:

1. Я понимаю. я должен использовать List.filter.

2. Привет, Джеффри, что, если я хочу сохранить некоторые элементы в одной структуре данных, и для этого не подходит прямое написание рекурсивной функции?

3. Короткий ответ: это всегда подходит! 🙂 Более длинный ответ: вы можете использовать изменяемые структуры, если у вас есть веская причина. Вам придется задать это как более конкретный, отдельный вопрос, чтобы получить лучший ответ.

4. Могу ли я List.filter остановиться на удалении одного элемента? Возможно, у меня есть копии элементов, которые выглядят одинаково, но я хочу удалить только один.

5. Чтобы ответить на мой собственный вопрос, одним из решений является использование Core filteri и фильтрация элемента по индексу элемента, который вы хотите удалить.

Ответ №2:

приведенные ниже коды возвращают новый список, в котором удаляются элементы, равные указанному ‘v’, из списка ‘l’.

 let remove l v equal =
  let rec aux l' v acc =
    match l' with
    | None -> acc
    | hd :: tl ->
      if equal hd v then
        aux tl v acc
      else
        aux tl v (hd :: acc)
  in
  aux l v []