国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

前端做模糊搜索

shadowbook / 1659人閱讀

摘要:到目前為止我們只實現(xiàn)了搜索功能,按更優(yōu)的體驗來講,在搜索結(jié)果中,要優(yōu)先把相連匹配的放在首位,如關(guān)鍵字,要把結(jié)果放到前面。

我們先看一下效果圖:

這是搜索關(guān)鍵字cfg時,會自動匹配到config方法

同樣,我們再看另一個例子


通過關(guān)鍵字bi會匹配到好幾個結(jié)果

這個和一些編輯器的搜索功能很像,比如sublime text,不需要知道關(guān)鍵字的完整拼寫,只需要知道其中的幾個字母即可。

那么這個功能在前端我們?nèi)绾稳崿F(xiàn)呢?

不考慮性能的話,我們可以用正則簡單實現(xiàn)如下:

把關(guān)鍵字拆分,加入(.?),如cfg最終為 (.?)(c)(.?)(f)(.?)(g)(.*?),然后拿這個正則去測試要搜索的列表,把符合要求的選項給拿出來即可

考慮到要高亮結(jié)果,我們還要生成對應(yīng)的替換表達(dá)式,最后的函數(shù)如下

var escapeRegExp = /[-#$^*()+[]{}|,.?s]/g;
var KeyReg = (key) => {
    var src = ["(.*?)("];
    var ks = key.split("");
    if (ks.length) {
        while (ks.length) {
            src.push(ks.shift().replace(escapeRegExp, "$&"), ")(.*?)(");
        }
        src.pop();
    }
    src.push(")(.*?)");
    src = src.join("");
    var reg = new RegExp(src, "i");
    var replacer = [];
    var start = key.length;
    var begin = 1;
    while (start > 0) {
        start--;
        replacer.push("$", begin, "($", begin + 1, ")");
        begin += 2;
    }
    replacer.push("$", begin);

    info = {
        regexp: reg,
        replacement: replacer.join("")
    };
    return info;
};

調(diào)用KeyReg把關(guān)鍵字傳入,拿返回值的regexp去檢測搜索的列表,把符合的保存下來即可。

到目前為止我們只實現(xiàn)了搜索功能,按更優(yōu)的體驗來講,在搜索結(jié)果中,要優(yōu)先把相連匹配的放在首位,如bi關(guān)鍵字,要把bind結(jié)果放到beginUpdate前面。第二個截圖是有優(yōu)化的地方的。

要完成這個功能,我們使用KeyReg返回值中的replacement,用它進(jìn)行檢測,把結(jié)果中長度最長的放前面即可,這塊代碼以后有時間再補(bǔ)充

2018.5.31
今天重構(gòu)了下,增加了結(jié)果排序,完整的代碼及使用示例如下

let Searcher = (() => {
    let escapeRegExp = /[-#$^*()+[]{}|,.?s]/g;
    let escapeReg = reg => reg.replace(escapeRegExp, "$&");
    //groupLeft 與 groupRight是對結(jié)果進(jìn)一步處理所使用的分割符,可以修改
    let groupLeft = "(",
        groupRight = ")";
    let groupReg = new RegExp(escapeReg(groupRight + groupLeft), "g");
    let groupExtractReg = new RegExp("(" + escapeReg(groupLeft) + "[sS]+?" + escapeReg(groupRight) + ")", "g");
    //從str中找到最大的匹配長度
    let findMax = (str, keyword) => {
        let max = 0;
        keyword = groupLeft + keyword + groupRight;
        str.replace(groupExtractReg, m => {
            //keyword完整的出現(xiàn)在str中,則優(yōu)秀級最高,排前面
            if (keyword == m) {
                max = Number.MAX_SAFE_INTEGER;
            } else if (m.length > max) {//找最大長度
                max = m.length;
            }
        });
        return max;
    };
    let keyReg = key => {
        let src = ["(.*?)("];
        let ks = key.split("");
        if (ks.length) {
            while (ks.length) {
                src.push(escapeReg(ks.shift()), ")(.*?)(");
            }
            src.pop();
        }
        src.push(")(.*?)");
        src = src.join("");
        let reg = new RegExp(src, "i");
        let replacer = [];
        let start = key.length;
        let begin = 1;
        while (start > 0) {
            start--;
            replacer.push("$", begin, groupLeft + "$", begin + 1, groupRight);
            begin += 2;
        }
        replacer.push("$", begin);

        info = {
            regexp: reg,
            replacement: replacer.join("")
        };
        return info;
    };

    return {
        search(list, keyword) {
            //生成搜索正則
            let kr = keyReg(keyword);
            let result = [];
            for (let e of list) {
                //如果匹配
                if (kr.regexp.test(e)) {
                    //把結(jié)果放入result數(shù)組中
                    result.push(e.replace(kr.regexp, kr.replacement)
                        .replace(groupReg, ""));
                }
            }
            //對搜索結(jié)果進(jìn)行排序
            //1. 匹配關(guān)鍵字大小寫一致的優(yōu)先級最高,比如搜索up, 結(jié)果中的[user-page,beginUpdate,update,endUpdate],update要排在最前面,因為大小寫匹配
            //2. 匹配關(guān)鍵字長的排在前面
            result = result.sort((a, b) => findMax(b, keyword) - findMax(a, keyword));
            return result;
        }
    };
})();

//假設(shè)list是待搜索的列表
let list = ["config", "user-page", "bind", "render", "beginUpdate", "update", "endUpdate"];
//假設(shè)userInput是用戶輸入的關(guān)鍵字
let userInput = "up";

//獲取搜索的結(jié)果
console.log(Searcher.search(list, userInput));
//?["(up)date", "begin(Up)date", "end(Up)date", "(u)ser-(p)age"]

對搜索結(jié)果中的內(nèi)容做進(jìn)一步處理渲染出來即可,比如把 ( 替換成 ) 替換成顯示到頁面上就完成了高亮顯示

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/95928.html

相關(guān)文章

  • UCloud控制臺產(chǎn)品升級!

    摘要:主機(jī)接入新表格組件支持拖拽調(diào)整表頭列寬背景現(xiàn)狀客戶對于主機(jī)名稱的命名規(guī)則廠商地域可用區(qū)產(chǎn)品業(yè)務(wù)服務(wù)內(nèi)網(wǎng),名稱較長,無法在列表頁直觀展示,只能手動上去顯示全部。如有關(guān)于控制臺產(chǎn)品的前端及視覺優(yōu)化建議也歡迎和我們部門同學(xué)反饋。2月份根據(jù)用戶反饋、用戶調(diào)研以及自身使用產(chǎn)品體驗,將主機(jī)列為重點體驗優(yōu)化目標(biāo)產(chǎn)品,主要針對如下業(yè)務(wù)場景進(jìn)行了優(yōu)化:主機(jī)創(chuàng)建頁可用區(qū)售罄地域切換優(yōu)化主機(jī)列表頁主機(jī)接入新表格組...

    ernest.wang 評論0 收藏0
  • 前端拼音模糊搜索

    摘要:前端實現(xiàn)拼音模糊搜索曾經(jīng)滄海難為水除卻巫山不是云曾我愛你中國我愛你中國愛你中 前端實現(xiàn)拼音模糊搜索pinyin-match[https://github.com/xmflswood/...[1] const PinyinMatch = require(pinyin-match);let test = 123曾經(jīng)滄海難為水除卻巫山不是云 PinyinMatch.match(test, 2...

    kel 評論0 收藏0
  • 前端拼音模糊搜索

    摘要:前端實現(xiàn)拼音模糊搜索曾經(jīng)滄海難為水除卻巫山不是云曾我愛你中國我愛你中國愛你中 前端實現(xiàn)拼音模糊搜索pinyin-match[https://github.com/xmflswood/...[1] const PinyinMatch = require(pinyin-match);let test = 123曾經(jīng)滄海難為水除卻巫山不是云 PinyinMatch.match(test, 2...

    fish 評論0 收藏0
  • 前端拼音模糊搜索

    摘要:前端實現(xiàn)拼音模糊搜索曾經(jīng)滄海難為水除卻巫山不是云曾我愛你中國我愛你中國愛你中 前端實現(xiàn)拼音模糊搜索pinyin-match[https://github.com/xmflswood/...[1] const PinyinMatch = require(pinyin-match);let test = 123曾經(jīng)滄海難為水除卻巫山不是云 PinyinMatch.match(test, 2...

    Apollo 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<