排序檢測演算法
阿新 • • 發佈:2018-11-13
時間: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(',')}`
}
複製程式碼
如此我們就完成了資料的校驗,而且方法適用性很強,若是有四個或者更多需要檢驗的元素也可以使用,無需擔心。