如何自定义排序 aAbBcC 即Excel中的排序,AaBbCc

 列举排序中的几种情况,然后逐个进行排序即可


const CHAR_CODE_a = 'a'.charCodeAt(0); // 97
const CHAR_CODE_A = 'A'.charCodeAt(0); // 65
const CHAR_CODE_z = 'z'.charCodeAt(0); // 112
const CHAR_CODE_Z = 'Z'.charCodeAt(0); // 90

const diffLowerUpper = CHAR_CODE_a - CHAR_CODE_A;

const isLower = (charCode) => {
    return CHAR_CODE_a <= charCode && charCode <= CHAR_CODE_z;
};
const isUpper = (charCode) => {
    return CHAR_CODE_A <= charCode && charCode <= CHAR_CODE_Z;
};
const ORDER = {
    KEEP : 1,
    EXCHANGE : -1,
    EQUAL : 0,
}
const A1Bigger = (isAsc) => {
    // 以降序的角度考虑,A1大,那么保持即可
    return isAsc ? ORDER.EXCHANGE : ORDER.KEEP;
};

const A2Bigger = (isAsc) => {
    // 以降序的角度考虑,A2大,那么需要跟A1交换位置
    return isAsc ? ORDER.KEEP : ORDER.EXCHANGE;
};
/**
 * 比较 A2 字符串与 A1 字符串在第index位谁更大
 * 这里的排序规则为: a < A < b < B < c < C 与OfficeExcel保持一致
 * @param A2 
 * @param A1 
 * @param isAsc 
 * @param index 
 */
const excelStringCompare = (A2, A1, isAsc, index = 0) => {
    if(A2 === A1) {
        return ORDER.EQUAL
    }
    const charCodeA1 = A1.charCodeAt(index), charCodeA2 = A2.charCodeAt(index)
    // 两个字串相等情况以及处理,会有NaN一定是有一个长度大于另一个,而charCodeAt(index)等于NaN的就说明他的长度更短
    if(isNaN(charCodeA1)) {
        return A2Bigger(isAsc);
    } else if(isNaN(charCodeA2)) {
        return A1Bigger(isAsc);
    }
    // 都是小写或都是大写
    if ((isLower(charCodeA1) && isLower(charCodeA2)) || (isUpper(charCodeA1) && isUpper(charCodeA2))) {
        if (charCodeA2 < charCodeA1) {
            return A1Bigger(isAsc);
        }
        if (charCodeA2 > charCodeA1) {
            return A2Bigger(isAsc);
        }
        // 当两个字符串这个位相等的时候再比较下个位
        return excelStringCompare(A2, A1, isAsc, index + 1 )
    }
    //  A1 小写   A2 大写
    else if (isLower(charCodeA1) && isUpper(charCodeA2)) {
        // a - A
        if (charCodeA1 - charCodeA2 === diffLowerUpper) {
            return A2Bigger(isAsc);
        } else {
            // c - (a - A) < D 即 (c - a = 2) < (D - A = 3)
            if (charCodeA1 - diffLowerUpper < charCodeA2) {
                return A2Bigger(isAsc);
            } else {
                return A1Bigger(isAsc);
            }
        }
    }
    // A1 大写   A2 小写
    else {
        // A - a === - (a - A)
        if (charCodeA1 - charCodeA2 === -diffLowerUpper) {
            return A1Bigger(isAsc);
        } else {
            // C + (a - A) < d 即 (C - A = 2) < (d - a = 3)
            if (charCodeA1 + diffLowerUpper < charCodeA2) {
                return A2Bigger(isAsc);
            } else {
                return A1Bigger(isAsc);
            }
        }
    }
};

const isAsc = true;// 升降序

let strArr = ['a','Ab', 'b', 'aB', 'A', 'B', 'ab', 'AB', 'c', 'D', 'd', 'C']

strArr.sort((a, b) => {
    return excelStringCompare(a, b, isAsc)
})

console.log(strArr)

排序结果: 

你可能感兴趣的:(算法,javascript)