【问题标题】:Prefer uppercase unique when doing case-insensitive sort removing duplicates inside web workers在进行不区分大小写的排序时首选大写唯一
【发布时间】:2014-10-06 17:41:14
【问题描述】:

我正在使用来自网页中元素的 data-* 属性的关键字填充自动完成下拉列表的 datalist 元素,并且在对它们进行排序和删除重复项时,我希望保留以大写开头的关键字而不是小写关键字。

我用于获取唯一关键字的代码也可能会使用一些优化来提高效率,尽管在 Web Worker 中运行它意味着这不是优先事项。

我尝试了使用 caseFirst:upper 选项的 localeCompare 技巧,但没有成功(或者如果重复删除代码更智能,也许可以)

TL;DR 我希望大写的 Foo/Bar/Baz 出现在自动完成下拉列表中,而不是 foo/bar/baz

<!DOCTYPE HTML><html lang="en"><head><meta charset="utf-8">
<title>Populate Autocomplete</title>
<script type="text/javascript">
function acEntries(dl,kwlist) {
    var blob = new Blob(Array.prototype.map.call(document.querySelectorAll("script[type=\"text\/js-worker\"]"), function (oScript) { return oScript.textContent; }),{type: "text/javascript"}),
    worker = new Worker(window.URL.createObjectURL(blob));
    Array.prototype.slice.call(document.querySelectorAll("dd[data-"+dl.toLowerCase()+"]")).forEach(function(g){
        var ds = g.dataset.fooTopics;
        if(!ds)return; /* Ensure there is a data- attribute of CSV keywords to include in the kwlist array */
        kwlist = kwlist.concat(ds.split(","));
    })
    worker.postMessage(kwlist); /* Asynchronously remove duplicate keywords and sort */
    worker.onmessage = function (ev) {
        var d = document.getElementById(dl),t = d.firstChild.content,v = ev.data,
        observer = new MutationObserver(function(mo) {
            t.firstChild.setAttribute("value",v.shift());
            if(v.length<1){observer.disconnect()}
            requestAnimationFrame(function(){d.appendChild(t.cloneNode(true))}); /* add the next keyword to datalist */
        }),
        config = {childList:true};
        t.firstChild.setAttribute("value",v.shift());
        observer.observe(d,config); /* watch for keywords being added to datalist */
        d.appendChild(t.cloneNode(true)); /* add the first keyword to the datalist */
        worker.terminate();
    }
}
</script></head><body onload="acEntries('Foo-topics',[])">
<dl><dt></dt>
    <dd data-foo-topics="Foo,bar,Baz">Foobar Baz</dd>
    <dd data-foo-topics="Floo,Bar,Blaz">Floobar Blaz</dd>
    <dd data-foo-topics="foo,Blah,baz">Fooblah Baz</dd>
</dl>
<input type="search" list="Foo-topics" placeholder="Foo-topics" autocomplete="off" aria-autocomplete="list">
<datalist id="Foo-topics"><template><option></template></datalist>
<script type="text/js-worker">
self.addEventListener('message', msgRcvd); 
function msgRcvd(er) {
    var arr = er.data.sort(function(a, b) {
                return a.localeCompare(b, {sensitivity:'base',caseFirst:'upper'});
            }),
        len = arr.length, nw = (len >= 1 ? [arr[0]] : []);
    for(var i = 1; i < len; i++) {
        if(nw[nw.length -1].toLowerCase() != arr[i].toLowerCase()) {
            nw.push(arr[i]);
        }
    }
    self.postMessage(nw);
}
</script></body></html>

http://htmlpad.org/ArrayComplete/edit玩它

【问题讨论】:

    标签: javascript arrays sorting web-worker case-insensitive


    【解决方案1】:

    我在看《三位医生》,有人建议“简单地反转极性!”然后它打动了我..

    由于 localeCompare 排序总是先排序数组小写,而不是从 arr[0] 开始并向前检查,然后将唯一值推到 nw[] 的末尾,为什么不从末尾开始,或者 arr[len],以及向后检查然后将唯一性取消移动到 nw[] 的开头?

    function msgRcvd(er) {
        var arr = er.data.sort(function(a, b) {
                    return a.localeCompare(b, {sensitivity:'base'});
                }),
            len = arr.length, nw = (len >= 1 ? [arr[len - 1]] : []);
        while(len--) {
            if(nw[0].toLowerCase() != arr[len].toLowerCase()) {
                nw.unshift(arr[len]);
            }
        }
        self.postMessage(nw);
    }
    

    使用 len 的 while 循环——而不是使用 i++ 的 for 循环

    我颠倒了极性,完美的 Whovian 解决方案 :)

    【讨论】:

      猜你喜欢
      • 2013-04-17
      • 2012-01-31
      • 1970-01-01
      • 1970-01-01
      • 2019-01-31
      • 2020-09-13
      • 2012-06-22
      • 1970-01-01
      • 2013-05-11
      相关资源
      最近更新 更多