2017-01-14 5 views
-2

Я работаю с refs, и мне нужна помощь.Clojure: работа с refs в коллекции

я здесь 2-х банковских счетов с соответствующим :operations

(ref :name "bank" 
     :accounts 
     {12345678 (ref {:name "joey" 
         :account-number 12345678 
         :operations (ref {:desc "DESC1" :amount 100 :date "2017-01-10"]}) 
            (ref {:desc "DESC2" :amount 200 :date "2017-01-11"]}) 
            (ref {:desc "DESC3" :amount 300 :date "2017-01-12"]})}) 
     {87654321 (ref {:name "paul" 
         :account-number 12345678 
         :operations (ref {:desc "DESC1" :amount 50 :date "2017-01-10"]}) 
            (ref {:desc "DESC2" :amount 10 :date "2017-01-11"]}) 
            (ref {:desc "DESC3" :amount 30 :date "2017-01-12"]})}) 
}) 

мне нужно получить все :operations со всех счетов, чтобы собрать коллекцию, как это:

[{:desc "DESC1" :amount 100 :date "2017-01-10"]} 
{:desc "DESC2" :amount 200 :date "2017-01-11"]} 
{:desc "DESC3" :amount 300 :date "2017-01-12"]} 
{:desc "DESC1" :amount 50 :date "2017-01-10"]} 
{:desc "DESC2" :amount 10 :date "2017-01-11"]} 
{:desc "DESC3" :amount 30 :date "2017-01-12"]}] 

Не нужно быть таким же его просто идея, я пытаюсь с map и deref, но все еще застрял.

+0

У меня есть вырубка, что '(ссылка: название "банк")' не действует, верно? –

+0

Что вы пробовали, и были ли вы застряли? Кстати, ваш код даже не читает * («непревзойденный разделитель»), а тем более * работает * в любой емкости. –

+0

Две вещи: пожалуйста, скажите мне, что это не настоящий код банка. : P И расскажите нам больше о том, почему ваши данные выглядят так. Тройные вложенные ссылки имеют запах кода. – jmargolisvt

ответ

1

У вас есть ряд проблем с кодом, который вам нужно будет разобраться. В то время как clojure имеет большую поддержку параллелизма/параллелизма, вы должны сначала получить основы правильно. Работа с несколькими потоками активности сложна и пытается это сделать, а также пытается выяснить, как работают основные структуры данных и основные функции, что делает ее практически невозможной.

  1. Ваша функция ref недействительна clojure. Документы для рефов состояния

Функции иого Использование: (исх х) (реф х & опции) Создает и возвращает реф с начальным значением х и нуля или более опций (в любом порядке):

: мета метаданные карта

: валидатор Validate-ф

: мин-истории (по умолчанию 0): макс-истории (по умолчанию 10)

Если будет предоставлена ​​карта метаданных, она станет метаданными на ссылке. validate-fn должен быть nil или без побочных эффектов fn одного аргумента, , который будет передан предполагаемому новому состоянию при любом изменении состояния. Если новое состояние неприемлемо, validate-fn должно возвращать false или выдать исключение. validate-fn будет вызываться при фиксации транзакции, , когда все refs имеют свои окончательные значения.

Обычно refs аккумулирует историю динамически по мере необходимости, чтобы иметь дело с читать требования. Если вы заранее знаете, что вам понадобится история, вы можете установить : min-history, чтобы убедиться, что она будет доступна, когда сначала понадобится (вместо этого после ошибки чтения). История ограничена, и предел может быть установлен с: max-history. Добавлено в версии Clojure 1.0

Два ключевых слова, которые у вас есть на старте, выглядят так, будто вы можете определить метаданные для ссылки. Вы должны использовать опцию: meta при определении ref (это догадка с моей стороны о том, каково ваше реальное намерение и может быть совершенно неверным).

  • Обязательным аргументом ref является начальное значение. Это должна быть действительная структура clojure или функция, которая возвращает ее. В вашем случае вы похожи на карту.

    1. Я не думаю, что вы хотите вставить рефери.Хотя технически, я думаю, вы можете определить их, это почти наверняка не то, что вы действительно хотите. Прочитайте refs and transactions, чтобы понять, почему вы, вероятно, не хотите этого делать и какое влияние оно оказывает на выполнение STM. Общее правило состоит в том, чтобы изолировать значения, необходимые для обеспечения управления. Вы нуждаетесь в мелкозернистом управлении доступом, и вы хотите избежать вложенного контроля доступа, так как это будет слишком сложным, и ваш контроль доступа станет ограниченным. Рассмотрите свои операции с банковским счетом. Вы не хотите блокировать все банковские счета, когда они работают только на одном или двух из них - вы просто хотите заблокировать/управлять обновлениями учетных записей. То, что вы, вероятно, хотите, это либо массив (вектор) ссылок, либо, возможно, нормальная хэш-карта, где один из ключей - это учетная запись, а значение - это ссылка, которая в свою очередь представляет собой карту со значениями, необходимыми для обеспечения, транзакция (другие варианты включают в себя семафор или подход к критическому региону, поскольку ref является простым флагом/блокировкой, который определяет, может ли транзакция продолжить или должна быть намотана назад и попыталась снова.

    2. Я думаю, вы можете захотеть немного подумайте о своей структуре данных. Играйте с хэш-картами немного и экспериментируйте с вложенными структурами. Играйте с основными функциями в этих базовых и вложенных структурах данных (карта, фильтр, сокращение, цикл/повторение, последовательности и лень и т. д.). Получить правильную абстракцию, а затем посмотреть, как вам нужно будет ее изменить, чтобы обеспечить согласованность ваших данных, то есть, как обеспечить вашу транзакцию ионы являются соответственно атомными, особенно когда задействованы несколько учетных записей. Ваша текущая вложенная структура недействительна - например, посмотрите на значение: операции. Какая ценность? Это вектор транзакций refs? Как clojure знает, что это вектор? Как ваше приложение должно извлечь эти данные? Какая самая частая операция - собрать все вместе или извлечь отдельные транзакции? Должны ли они быть в порядке даты? Насколько легко получить транзакцию на определенную дату? Будет ли эта шкала, если у вас есть сотни счетов с тысячами транзакций? и т. д. Получите правильную абстракцию, и легкие вещи все равно будут легкими. Получите это неправильно, и легкие вещи будут трудными, и тяжелые вещи, вероятно, будут еще сложнее.

Смежные вопросы