2017-01-14 61 views
-2

我正在與裁判合作,我需要一些幫助。Clojure:與集合中的裁判工作

我這裏有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"]}] 

不需要相同的只是一個想法,我想用mapderef但仍然卡住。

+0

我有感覺的是'(參考:名稱爲 「銀行」)'是無效的,對不對? –

+0

你有什麼嘗試過,並且被卡住了嗎?順便說一句,你的代碼甚至不讀*(「無與倫比的分隔符」),更不用說*任何容量的工作*。 –

+0

兩件事:請告訴我這不是真正的銀行代碼。 :P並告訴我們更多關於爲什麼你的數據看起來像這樣。三重嵌套參考有代碼味道。 – jmargolisvt

回答

1

您的代碼有許多問題需要您解決。雖然clojure對並行/併發有很大的支持,但你需要先把基礎知識做好。處理多個線程的活動非常困難,並試圖做到這一點,同時試圖找出基本的數據結構和核心功能如何工作將使其幾乎不可能。

  1. 您的ref函數不是有效的clojure。對於參考狀態的文檔

REF功能用途:(參照X) (參照X &選項)創建並返回一個參考,其中x和零個或多個選項(以任何順序)的初始值:

:元元數據的地圖

:驗證器驗證-FN

命令min-歷史(默認爲0):最大歷史(默認10)

如果提供了元數據映射,它將成爲ref上的元數據。 validate-fn必須爲零或一個參數的無副作用fn, 將在任何狀態更改時通過預期的新狀態。如果 新狀態是不可接受的,則validate-fn應該返回false或 拋出異常。當所有ref都有其最終值時,將在事務提交時調用validate-fn, 。

通常會根據需要動態地累積歷史記錄以處理 讀取需求。如果您事先知道您需要歷史記錄,您可以設置最小歷史記錄,以確保在首次需要時它可用(代替 之後的讀取故障)。歷史是有限的,可以使用max-history將限制設置爲 。在Clojure版本1.0中添加

您在開始時看到的兩個關鍵字看起來像您可能正試圖爲ref定義元數據。在定義ref時,你需要使用:meta選項(這是我的猜測,關於你的真實意圖,可能完全不正確)。

  • ref的強制參數是初始值。這需要是一個有效的clojure'結構'或返回一個函數。在你的情況下,你看起來像你想要一張地圖。

    1. 我不認爲你想要嵌套的參考。雖然在技術上,我認爲你可以定義它們,這幾乎肯定不是你真正想要的。請閱讀refs and transactions以瞭解爲什麼你可能不想這樣做,以及它對STM的影響。一般的經驗法則是隔離您需要確保管理的值。您需要細粒度的訪問控制,並且您希望避免嵌套的訪問控制,因爲這會使事務過於複雜,並且您的訪問控制將變爲過程粒度。考慮你的銀行賬戶操作。您不想鎖定所有銀行賬戶,只需要在其中的一個或兩個銀行賬戶上操作 - 您只想鎖定/控制所涉及賬戶的更新。你可能想要的是一個refs的數組(向量),或者是一個正常的哈希映射,其中一個鍵是帳戶,值是ref,然後是具有需要確保更新的值的映射一個交易(其他選擇將包括一個信號量或關鍵區域的方法,這個參考是一個簡單的標誌/鎖定,它確定交易是否可以繼續或者必須重新開始並且再次嘗試)

    2. 我想你可能想要仔細考慮一下你的數據結構,用哈希映射稍微玩一下,並試驗嵌套結構。在這些基本和嵌套數據結構(映射,過濾,減少,循環/重複,序列和懶惰等)上播放核心函數。 。正確地獲取基本抽象,然後研究如何改變它以確保數據的一致性,即如何確保您的事務處理離子適當地是原子的,特別是當涉及多個賬戶時。您當前的嵌套結構無效 - 例如,查看:operations值。那有什麼價值?它是交易參考的矢量嗎? clojure如何知道這是一個向量?您的應用程序需要如何提取該數據?什麼是最常見的操作 - 一起提取或提取單個交易?他們需要按日期順序嗎?在特定日期獲得交易有多容易?一旦您擁有數以千計的交易賬戶,這種規模是否會擴大?等等。讓你的抽象正確,簡單的事情仍然很容易。搞錯了,簡單的事情就會變得艱難,困難的事情可能會更加困難。