在执行不区分大小写的排序以删除web工作程序中的重复项时,首选大写字母唯一

Prefer uppercase unique when doing case-insensitive sort removing duplicates inside web workers

本文关键字:大写字母 唯一 工作程序 不区 执行 大小写 排序 web 删除      更新时间:2023-09-26

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

我获取唯一关键字的代码可能也需要一些优化来提高效率,尽管在网络工作者中运行它意味着这不是优先事项。

我尝试了一个localeCompare技巧来处理caseFirst:上部选项,但这并没有起到作用(或者如果重复删除代码更聪明的话,也许可以)

TL;DR我希望大写的Foo/Bar/Baz位于自动完成下拉列表中,而不是Foo/Bar/Biz

<!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

我在看《三个医生》,有人建议"简单地反转极性!"然后我突然想到了…

既然localeCompare排序总是先对数组进行小写排序,而不是从arr[0]开始并向前检查,然后将uniques推到nw[]的末尾,为什么不从末尾或arr[len]开始并向后检查,然后取消将unique斯推到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解决方案:)