2012-07-20 67 views
0

考慮以下情況:如何管理原始對象之間的數據依賴關係?

items = [ 
    { 
    id: 1 
    attributes: [ 
     { key: a, value: 2 } 
     { key: b, value: 3 } 
    ], 
    requirements: null 
    } 
    { 
    id: 2 
    attributes: [ 
     { key: b, value: 2 } 
    ], 
    requirements: a > 2 
    } 
    { 
    id: 3 
    attributes: [ 
     { key: a, value: 1 } 
     { key: c, value: 1 } 
    ], 
    requirements: a > 1 and b > 2 
    } 
    { 
    id: 4 
    attributes: [ 
     { key: a, value: 2 } 
     { key: d, value: 7 } 
    ], 
    requirements: b > 5 and h < 10 
    } 
] 

預期的結果,相加(總和)的各種attributes是:在對象之間

result = [ 
    { key: a, value: 3 } 
    { key: b, value: 5 } 
    { key: c, value: 1 } 
] 

正如你可以看到,有依賴關係(requirements)名單。特別是,因爲從不檢查條件b > 5 and h < 10,所以id: 4(系列中的最後一個)的對象從計算中被丟棄。相反,具有id: 2的對象最初被丟棄,然後作爲id: 3(通過將屬性a加上1,使條件爲a > 2)的對象的結果落入計算中。

獲得具有N個對象的所需結果所需的算法是什麼?

聲明:所提出的結構只是一個例子。您可以建議您相信實現結果的任何更改。我正在使用JavaScript(CoffeeScript)編程語言,但其他任何都可以。

+0

您是否有時間或空間複雜性要求?顯而易見的解決方案是'O(n^2)' - 你放棄了這個選擇嗎?另外,你需要一些方法來存儲需求(當'items'被實例化時,你的當前代碼將評估它們爲布爾值,所以它們不能被重新檢查。你解決了這個問題,還是它也是你問題的一部分? – 2012-07-20 17:40:49

+0

@AaronDufour對'需求'鍵的評估並不打算在對象實例化上進行,而是在每次被稱爲'sum'方法時進行;我認爲有必要在每個項目的需求之間建立某種聯繫條件和'sum'過程(一個事件驅動的方法?):每個對象都應該監聽數組中的變化(item add/remove),並且如果符合條件,則將其狀態更改爲'active = true'(或然後list對象再次執行'sum',最終導致其他對象激活,等等。無論如何,這只是一個想法。 – Jerus 2012-07-23 09:44:31

回答

0

讓我們開始以我們可以使用的格式獲取數據。我們需要能夠測試隨意的要求,而不是隻有當數據對象實例化:

{ 
    id: 4 
    attributes: [ 
     { key: a, value: 2 } 
     { key: d, value: 7 } 
    ], 
    requirements: (sum) -> sum.b > 5 and sum.h < 10 
    } 

雖然我們在這,讓我們的屬性在一個更有用的狀態(注意,這ISN」牛逼絕對必要的,但讓一切更簡單):

{ 
    id: 4 
    attributes: { 
     a: 2 
     d: 7 
    }, 
    requirements: (sum) -> sum.b > 5 and sum.h < 10 
    } 

現在我會去通過天真的算法,這是最簡單的,應該滿足您的需求。本質上,我們將繼續循環數據集,測試每個尚未使用的數據集,並在數據集通過時將其添加到總和中。

changed = true 
sum = {} 
init(sum, items) 
while changed 
    changed = false 
    for item in items 
     if !item.used && item.requirements(sum) 
      add(sum, item.attributes) 
      changed = true 
      item.used = true 

我會讓你在addinit功能填補。 add一個應該是簡單的;它將第二個參數中的每個元素添加到第一個元素中的每個元素。 init需要將sum中的每個元素設置爲0,這些元素可能會被使用(測試或添加到)。

+0

感謝您提供寶貴的建議和詳細的解釋。事件驅動實現解決這個問題,但你的方法無疑更聰明和優雅。所以代碼少,複雜度低。再次感謝。 – Jerus 2012-07-26 08:46:31