javascript黑科技之高效填充

post200發表於2021-09-09

前兩天看了下導致react、babel打包失敗的left-pad 14行原始碼,的確是存在黑科技啊,可以把填充縮短到只填充2的n次方中的n次。其中還有關於位運算子的運用,很好很強大。

不過由於太簡單了,程式碼太少,所以運用場景比較單一,一些複雜場景也不能返回正確想要達到的值。我就在這基礎上進行了最佳化,並且給出了位操作的替代處理方案,效率和原始碼一樣。以下是相關程式碼,並在github上附上了對應的單元測試:

/**
 * Created by lenovo on 2017/6/13.
 */
/**
 * 高效填充字元函式(填充次數為2的n次方中的n次)
 * @param  {string}  str    待填充的字串
 * @param  {number}  len    填充後的長度
 * @param  {any}     ch     填充物,可以單個字元,也可以多個字元。
 * @param  {any}     direct 填充位置(r: 右填充,其他:左填充)
 */
function pad(str, len, ch, direct) {
    var left = '', //超出的填充字元
        pad = '', // 完整填充字元
        ch = ch + ''; //填充物

    //完整填充字元
    len = len - str.length;

    // 1、填充長度必須大於0,否則返回原字串,例如(pad('aa', 0, 'tabca'))
    if (!(len >= 0)) return str;

    if (ch.length > 0 && len % ch.length !== 0) {
        console.log(222)
        //2、不能正好完整填充,則會有超出的填充字元,例如(pad('aa', 7, 'tabc'))
        left = ch.slice(0, len % ch.length);
    }

    // 3、獲取實際填充長度,如果超過一個字元,填充次數會相應除去,例如(pad('aa', 7, 't')和2)
    len = Math.floor(len / (ch.length));

    while(true) {
        // 4、長度如果為偶數,則直接對摺加如果不是,最後長度為0也會進入該函式,例如(pad('aa', 10, 'taca')和2)
        if (len % 2) pad += ch;// if (len & 1) pad += ch;
        len >>= 1;// len = Math.floor(len / 2);
        if (len) ch += ch;
        else break;
    }
    // 5、預設為左填充,如果想右填充則direct傳'r',例如(pad('aa', 7, 't','r')和2)
    if (direct === 'r') {
        return str + pad + left;
    } else {
        return left + pad + str;
    }
}

module.exports = pad;

github地址:
上面有詳細的單元測試,歡迎大家fork。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2249/viewspace-2807842/,如需轉載,請註明出處,否則將追究法律責任。

相關文章