時間:2018年11月02日
比方說有這樣一堆資料:
arr: [{
id: '1',
type: 'a',
arr: [1, 2, 3, 4]
}, {
id: '2',
type: 'b',
arr: [1, 2, 3, 4, 5]
}]
複製程式碼
集合裡面每個元素都有兩個屬性,一個是type
,一個是arr
,arr
是一個陣列。
需求是先判斷屬性,不同屬性對arr
的長度有著不同的需求。這裡我們規定type
若是‘a’,arr
的長度最多為4。type
若是‘b’,arr
的長度最多為6;兩者的報錯內容也並不相同。
我的本意是迴圈目標陣列,之後先判斷是否符合type
,再判斷arr
是否符合條件,將不符合條件元素的id
存到一個陣列中,最後展示出來:
aError = [];
bError = [];
_.each(arr, (op) => {
if (op.type === 'a') {
if (op.arr.length > 4) {
aError.push(op.id);
}
}
if (op.type === 'b') {
if (op.arr.length > 6) {
bError.push(op.id);
}
}
})
if (aError) {
const errMsg = `a的報錯提示:${aError.join(',')}`;
}
if (bError) {
const errMsg = `b的報錯提示:${bError.join(',')}`;
}
複製程式碼
寫完之後自我感覺還是不錯的,看上去挺清楚的,邏輯什麼的也很簡單,如果還有其他的再增加就好了。
問題是寫完之後和同事討論了一下,覺得程式碼的複用性太差,如果有新的條件會增加更多的程式碼,這種重複造輪子的操作感覺不是很好。所以商討之後我們決定將條件寫成一個配置檔案,通過讀取配置檔案來解析條件,再進行判斷。
那麼配置檔案需要什麼內容呢?主要有三部分,type
型別、最大arr
數量,還有報錯資訊,所以我們決定了配置檔案的格式:
limitRule = {
a: {
max: '4',
errMsg: 'content'
},
b: {
max: '6',
errMsg: 'content'
}
}
複製程式碼
直接把type
型別當做了配置元素的key
,減少了一個屬性。之後我們就要開始迴圈配置檔案了。
let limitIds = {};
const limitErrMsg = [];
_.each(arr, (op) => {
if (_.keys(limitRule).includes(op.type)) { //獲取到配置檔案中所有的型別,之後判斷當前型別是否在配置檔案中
if (op.arr.length > limitRule[op.type].max) {
if (limitIds[op.type]) {
limitIds[op.type].push(op.id); //如果已經有這個type就直接push
} else {
limitIds[op.type] = [op.id]; //如果沒有這個type就新建陣列
}
}
}
})
複製程式碼
這裡的_.key
是lodash
中獲取物件key
的方法。先判斷下當前元素的type
是否在配置檔案中,如果在再進行下一步判斷,判斷當前元素陣列的長度是不是大於配置檔案中當前配置的max
值。若是大於,再將當前元素的id
放到limitIds
物件中,如果limitIds
中沒有當前型別的資料,則新建一個,若是有則push
進去。如此,我們得到的limitIds
應該是這樣的:
{
a:[1, 3, 7],
b: [7, 9, 10]
}
複製程式碼
接下來我們處理下limitIds
,得到報錯資訊:
_.mapObject(limitIds, (value, key) => {
if (value) {
limitErrMsg.push(`${limitRule[key].errMsg}${value.join(',')}`)
}
})
複製程式碼
如此我們就將所有的報錯資訊放到limitErrMsg
中了,之後輸出即可。整體方法是這樣的:
// 配置檔案
limitRule = {
a: {
max: '4',
errMsg: 'content'
},
b: {
max: '6',
errMsg: 'content'
}
};
// 新建儲存資訊的變數
let limitIds = {};
const limitErrMsg = [];
// 處理資料
_.each(arr, (op) => {
if (_.keys(limitRule).includes(op.type)) { //獲取到配置檔案中所有的型別,之後判斷當前型別是否在配置檔案中
if (op.arr.length > limitRule[op.type].max) {
if (limitIds[op.type]) {
limitIds[op.type].push(op.id); //如果已經有這個type就直接push
} else {
limitIds[op.type] = [op.id]; //如果沒有這個type就新建陣列
}
}
}
})
// 得到錯誤資訊
_.mapObject(limitIds, (value, key) => {
if (value) {
limitErrMsg.push(`${limitRule[key].errMsg}${value.join(',')}`)
}
})
複製程式碼
如此就將不同的判斷條件整合成了一個配置檔案,之後若是還有類似的配置直接修改配置檔案即可,簡直不要太方便。