排序檢測演算法

rexkentzheng發表於2018-11-07

時間: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(',')}`
}
複製程式碼

如此我們就完成了資料的校驗,而且方法適用性很強,若是有四個或者更多需要檢驗的元素也可以使用,無需擔心。

相關文章