Clojure - карта или набор с фиксированным значением -> ключевая функция? - PullRequest
5 голосов
/ 16 февраля 2011

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

(defrecord Foo. [id afield anotherfield])

А потом я добавлю это на карту с идентификатором в качестве ключа. Это все вполне выполнимо, но немного утомительно, например. при добавлении нового экземпляра Foo на карту мне нужно сначала извлечь ключ. Мне интересно, если где-то в clojure.core структура данных для этого уже существует?

По сути, я хотел бы создать набор Foo, задав набору значение функции сопоставления клавиш (т. Е. Id) во время создания набора, а затем использовал его, когда я хочу добавить / найти / удалить / ... значение.

Так что вместо:

(assoc my-map (:id a-foo) a-foo))

Я мог бы сделать, скажем:

(conj my-set a-foo)

И что еще интереснее, объединение и объединение с поддержкой.

Ответы [ 2 ]

3 голосов
/ 20 февраля 2011

Похоже на простой случай, когда вы захотите использовать функцию для устранения «утомительной» части.

Например,

(defn my-assoc [some-map some-record]
  (assoc some-map (:id some-record) some-record))

Если вы делаете это много и вам нужны другиеключевые функции, вы можете попробовать функцию более высокого порядка:

(defn my-assoc-builder [id-function]
  (fn [some-map some-record] 
    (assoc some-map (id-function some-record) some-record)))

(def my-assoc-by-id (my-assoc-builder :id))

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

1 голос
/ 17 февраля 2011

Так как (AFAIK) такой структуры данных нет (и даже если бы она существовала, она, вероятно, выполняла бы те же самые утомительные действия в фоновом режиме), вы можете использовать свои записи fns для желаемых операций (которые в фоновом режиме будут выполнять те же самые утомительные действия). вещи, которые нужно сделать).

В основном я хотел бы построить набор из Foo, давая множество значение функция сопоставления клавиш (т.е. идентификатор) в время строительства набора, а затем использовал, когда я хочу добавить / найти / удалить /...

Не получил это .. Если вы держите свои записи в наборе, а затем хотите, например, найти по идентификатору вам придется проделывать еще более утомительную работу, просматривая каждую запись, пока не найдете нужную… это O (n), а при использовании карты у вас будет O (1). Я слишком много использовал утомительно? Я предлагаю использовать карту и делать некоторые утомительные вещи .. Это все 1 и 0 в конце концов:)

...