2017-05-10 70 views
1

我對JS中的一些現有代碼有設計煩惱。代碼正在工作,所以我不急於改變它,但下面顯示的重複確實讓我煩惱。避免這種情況的常用/推薦/正式方法是什麼?避免重複鍵/數據

實際系統是一個大/複雜的金融系統,所以我把它簡化爲這表明了問題的最簡單的例子:

var colours={ 
    red:{id:"red", vals:[1,0,0]}, 
     green:{id:"green", vals:[0,1,0]}, 
     grey:{id:"grey", vals:[0.5,0.5,0.5]} 
// ...etc 
    }; 

// id needs to be known internally within the object - thus it is defined as a property. 
// e.g: 
colour.prototype.identify(console.log(this.id)); 

// id also needs to be used externally to find an object quickly. 
// e.g: 
function getcolour(s){return colours[s];} 

// Although this works. It does mean duplicating data, with the theoretical possibility of a mismatch: 
var colours={//... 
     blue:{id:"green", // oh dear... 

這將如何通常由專家來處理?

+0

看看到[lodash(HTTPS ://lodash.com/)庫 –

回答

1

這個問題有點主觀。

當創建我的應用我通常會嘗試做做到以下幾點:

  • 從未在多個地方定義相同的數據。源應該始終明確
  • 如果我需要創建任何索引更快/更容易的訪問,我使用實用方法來做到這一點。這些方法應該進行適當的單元測試,這樣我就不會懷疑他們做錯了什麼。
  • 儘可能使用第三方庫(例如已經建議的lodash或下劃線)以儘量減少代碼量採寫/維持。

如果您的算法和實用程序經過適當的單元測試,您不必擔心(太多)有關將數據置於不一致狀態的問題。但是,如果這些是非常重要的系統/接口,則可以在輸出上添加一些驗證。對輸入進行數據驗證和編組通常是一種很好的做法。

解釋的實用方法: 如果你有數據陣列,說

var data = [{"id":"i_1", ...}, {"id":"i_2", ...},{"id":"i_3",....}]; 

然後,你必須在原有基礎陣列上進行的,要創建一個索引或創建多個數據集,然後創建你自己是一個工具方法庫,它可以對數組進行修改,創建派生數據集或對數組進行迭代並隨時創建結果項目。例如:

var createIndex = function(arr){ 
    // do something that converts the data array with expected structure to object 
    // { 
    //  i_1: {"id":"i_1", ...}, 
    //  i_2: {"id":"i_2", ...}, 
    //  i_3: {"id":"i_3", ...} 
    return newObj; 
} 

該方法將創建一個哈希映射來訪問您的數據,這樣可以更快地遍歷原始數組。但現在,您可以輕鬆進行單元測試,並確保在源數據上使用它來獲取預期數據集時,這種方法不會出現不一致。

+0

同意第1點 - 這就是我問這個問題的全部原因。 您可否詳細說明'實用方法'將如何授予比顏色[s]更快的訪問權限。我不遵循你的思路。 – Richard

+0

@Richard在答案中加了說明 –

1

我不會改變顏色[鍵]直接訪問與其他方法,以避免重複。 任何其他嘗試都會導致處理,並且您提到您擁有大量數據。

我假設重複是在傳入的數據是浪費。 通過網絡數據消費進行處理的示例可能是,通過地圖對象並根據關鍵字動態設置標識。 (處理vs流量)

colours[key].id = key 
+0

如果問題不夠明確,請原諒我。沒有重複的對象 - 代碼工作正常。重複是密鑰存儲兩次的面,所以可能(理論上)不一致。 沒有實際的問題需要解決 - 我只是在尋找避免這種不雅設計的技巧。 – Richard

+0

我明白了,但是數據是否像您所描述的那樣來自服務器?如果是這樣,我試圖解釋爲什麼有時候你想堅持像你這樣的解決方案,而不是改變它,因爲像其他解決方案,如某人在這裏給出的處理將花費時間,特別是當涉及大數據時。我給你的例子將添加處理並刪除一些不必要的重複數據,你可以在客戶端處理 - 重複的我指的是綠色:{vals:[0,1,0]}而不是綠色:{id:「green」, vals:[0,1,0]}較小的數據流量 – lastboy

1

您可以過濾對象,將其轉換爲對象數組,然後過濾唯一值。將它轉換爲數組可以讓你更快更簡單地執行大量操作。

所以您可以將對象映射到一個數組:

var coloursArray = myObj.map(function(value, index) { 
    return [value]; 
}); 

刪除重複:

function removeDuplicates() { 
    return coloursArray.filter((obj, pos, arr) => { 
     return arr.map(mapObj => mapObj[id]).indexOf(obj[id]) === pos; 
    }); 
} 

您可以使用例如數組刪除重複underscore.js通過.uniq method

var uniqueColoursArray = _.uniq(coloursArray , function(c){ return c.id; }); 

此外,這個功能是相當無用的,因爲您可以訪問你的元素直接:

function getcolour(s){return colours[s];} 

調用colours[s]它也比getcolour(s)短。如果您傳遞數組是因爲它在其他範圍內無法訪問,那麼您的函數將有意義。

然後我不明白你爲什麼傳遞的console.log作爲參數在這裏:

colour.prototype.identify(console.log(this.id)); 

也許你想通過剛剛this.id

+0

我擔心我沒有足夠清楚地解釋問題。 我不想從數組中刪除重複的元素。我擔心datum(id)被重複存儲在兩個獨立的位置:作爲封閉對象中的鍵和子對象的屬性。 我只是想知道是否有一種我忽略的巧妙設計方法,可以避免這種情況。 – Richard

+0

是的,它不明確。只需改變你的設計: 'var colors = [ {id:「red」,vals:[1,0,0]}, {id:「green」,vals:[0,1,0] }, {id:「gray」,vals:[0.5,0.5,0.5]} ];' – quirimmo