排序檢測演算法
時間:2018年11月02日
有一列資料需要進行內容的校驗,總共有三個,如果有第一個,第二第三可以為空;有第一第二,第三可以為空;有第一和第三,第二不能為空;有第二和第三,第一不能為空;三者可以同時為空,以此類推。如下表所示
1 | 2 | 3 | OK? |
---|---|---|---|
無 | 無 | 無 | Y |
有 | 無 | 無 | Y |
有 | 有 | 無 | Y |
有 | 有 | 有 | Y |
有 | 無 | 有 | N |
無 | 有 | 有 | N |
無 | 有 | 無 | N |
無 | 無 | 有 | N |
總體就分這八種情況,四種可能,四種不可能。
一開始我的思維邏輯出了問題,覺得應該一層層判斷,比方說這樣:
if (condition) { if (condition) { if (condition) { } } else { if (condition) { } else { } } } else { } 複製程式碼
通過這樣來一層層判斷,可是這實在是很沒有邏輯的程式碼,不僅看上去很詭異 ,而且若是日後需要改,改的那個人看到這段程式碼也會噴死我的。
又或者說我可以列出這4種情況,然後所有的情況都檢測一遍,比方說這樣:
if (condition1 || condition2 || condition3 | condition4) { } else { } 複製程式碼
看上去還可以,但實際問題是condition
不可能這麼短,實際還是比較長的,所以只能另尋他法。
仔細思考之後,加上同事的幫助,我們可以發現在正確的情況下,最後一個有值的資料之前沒有空。這是什麼意思呢?比方說有-有-無
這種情況, 最後一個有值的資料是第二個有,第二個有之前沒有空的資料,所以這種情況是正確的。那麼有-無-有
這種情況,最後一個有值的資料是第三個有,但這裡的第二個是空,所以不成立,是錯誤的。
那麼在這種情況下,我們可以想到通過對比來資料的index
值來判斷是否正確,首先我們需要獲取到原生陣列的index
值,我們可以把這個值放到資料中的元素中:
arr = _.map(arr, (op, index) => ({ ...op, index, })); 複製程式碼
_.map
方式是lodash
提供的一個迴圈集合的方法,我們直接return
一個值,return
的結果中包含了原生的op
,同時增加了index
屬性,使用的是ES6的解構賦值方法。這樣我們集合中的元素就有了index
屬性了。
之後我們再獲取到過濾之後的集合,使用lodash
的_.filter
方法:
const existence = _.filter(arr, (op) => { return (op.code != null) && op.code.trim() !== ''; //這裡的code就是我們之前說的是否為空的值 }); 複製程式碼
這樣我們就獲取到了過濾之後的資料,接下來我們開始進行對比:
const errArr = []; const len = existence.length; if (len !== 0 && len - 1 !== existence[len - 1].index) { errArr.push(arr[0].id); } 複製程式碼
對比完成之後我們就可以通過判斷errArr
的長度來判斷是否有錯:
if(errArr.length > 0) { const errorMessage = `錯誤的地方有:${errArr.join(',')}` } 複製程式碼
所以整體程式碼是這樣的:
//定義方法 const verification = (arr) => { const errArr = []; arr = _.map(arr, (op, index) => ({ ...op, index, })); const existence = _.filter(arr, (op) => { return (op.code !== null) && op.code.trim() !== ''; }); const len = existence.length; if (len !== 0 && len - 1 !== existence[len - 1].index) { errArr.push(arr[0].id); } return errArr; } //呼叫方法 const errArr = []; _.each(allArr, (arr) => {//迴圈所有需要檢測的元素 errArr = errArr.concat(verification(arr));//進行檢測 }) if(errArr.length > 0) { const errorMessage = `錯誤的地方有:${errArr.join(',')}` } 複製程式碼
如此我們就完成了資料的校驗,而且方法適用性很強,若是有四個或者更多需要檢驗的元素也可以使用,無需擔心。