j查询或下划线 按范围文本对列表进行排序

jQuery or underscore Sorting a list by span text

本文关键字:列表 排序 文本 范围 查询 下划线      更新时间:2023-09-26

我有点迷茫地试图按 li 中的跨度对 ul 列表进行排序。
这是我的 html 代码:

<ul id="appsList">
    <li><span>aa</span>  <span class="sort">android</span></li>
    <li><span>aa</span>  <span class="sort">ios</span></li>
    <li><span>aa</span>  <span class="sort">facebook</span></li>
    <li><span>bb</span>  <span class="sort">android</span></li>
    <li><span>bb</span>  <span class="sort">ios</span></li>
    <li><span>bb</span>  <span class="sort">facebook</span></li>
</ul>

我有一个保存平台名称的数组,不必包含所有平台,数组中平台的顺序无关紧要。我希望列表按字母顺序排序,然后按第一个跨度的字母顺序。

因此,如果我的数组是["ios","android","facebook"]我想按字母顺序排列数组中的元素以及它们的第一个跨度值排序。因此,在对数组进行排序后,我们将得到:

<ul id="appsList">
    <li><span>aa</span>  <span class="sort">android</span></li>
    <li><span>bb</span>  <span class="sort">android</span></li>
    <li><span>aa</span>  <span class="sort">facebook</span></li>
    <li><span>bb</span>  <span class="sort">facebook</span></li>
    <li><span>aa</span>  <span class="sort">ios</span></li>
    <li><span>bb</span>  <span class="sort">ios</span></li>
</ul>

如果数组只是["ios"]则按数组元素的字母顺序排序,然后按字母顺序排序列表的其余部分:

<ul id="appsList">
    <li><span>aa</span>  <span class="sort">ios</span></li>
    <li><span>bb</span>  <span class="sort">ios</span></li>
    <li><span>aa</span>  <span class="sort">android</span></li>
    <li><span>bb</span>  <span class="sort">android</span></li>
    <li><span>aa</span>  <span class="sort">facebook</span></li>
    <li><span>bb</span>  <span class="sort">facebook</span></li>
</ul>

如果数组["ios","android"]则"android"将在"ios"之前和"facebook"之后,因为"facebook"不在数组中:

<ul id="appsList">
   <li><span>aa</span>  <span class="sort">android</span></li>
   <li><span>bb</span>  <span class="sort">android</span></li>
   <li><span>aa</span>  <span class="sort">ios</span></li>
   <li><span>bb</span>  <span class="sort">ios</span></li>
   <li><span>aa</span>  <span class="sort">facebook</span></li>
   <li><span>bb</span>  <span class="sort">facebook</span></li>
</ul>

这就是我到目前为止所做的:PLNKER

如果这可以使用下划线轻松完成,我更喜欢这样。谢谢。

您需要通过过滤和排序来分解任务。然后合并两个结果。

普伦克演示

 var arr = ["ios"];
 var $li = $('#appsList li').clone();
 var mySort = function(a, b) {
        var objA = {
            "span": $(a).find('span').not('.sort').text(),
            "sort": $(a).find('.sort').text()
        }
        var objB = {
            "span": $(b).find('span').not('.sort').text(),
            "sort": $(b).find('.sort').text()
        }
        output = objA.sort.localeCompare(objB.sort);
        if (objA.sort === objB.sort) {
            output = objA.span.localeCompare(objB.span);
        }
        return output
    } // mySort
 // Filter for what's in your array
 var arrFilter = function(index, el) {
    return arr.indexOf($(el).find('.sort').text()) > -1;
 }
 // Filter for what's not in your array
 var notArrFilter = function(index, el) {
    return arr.indexOf($(el).find('.sort').text()) < 0;
 }
 var $arrLi = $li.filter(arrFilter);
 var $notArrLi = $li.filter(notArrFilter);
 $arrLi = $arrLi.sort(mySort);
 $notArrLi = $notArrLi.sort(mySort);
 var $newLi = [];
 $.merge($newLi, $arrLi);
 $.merge($newLi, $notArrLi);
 $('#resultAppsList').html($newLi);

我的建议是:

Number.prototype.pad = function(size) {
  var s = String(this);
  while (s.length < (size || 2)) {s = "0" + s;}
  return s;
};
function doStuff(arr) {
  var listAllUniqueEle = $.unique($('#appsList li .sort').map(function(index, element) {
    return element.textContent;
  })).sort().toArray();
  listAllUniqueEle = $.unique(arr.sort().concat(listAllUniqueEle));
  var $li = $('#appsList li').clone().sort(function(a, b) {
    var firstValue =  listAllUniqueEle.indexOf(a.childNodes[2].textContent).pad(3) +
        a.textContent + a.textContent;
    var secondValue = listAllUniqueEle.indexOf(b.childNodes[2].textContent).pad(3) +
        b.textContent;
    return firstValue.localeCompare(secondValue);
  });
  $('#resultAppsList').empty().html($li)
}
$(function () {
  $('#btn1').on('click', function(e) {
    doStuff(["ios","android","facebook"]);
  });
  $('#btn2').on('click', function(e) {
    doStuff(["ios"]);
  });
  $('#btn3').on('click', function(e) {
    doStuff(["ios","android"]);
  });
});
<script src="https://code.jquery.com/jquery-1.12.1.min.js"></script>
<button id="btn1">["ios","android","facebook"]</button>
<button id="btn2">["ios"]</button>
<button id="btn3">["ios","android"]</button>
<br>Before sort :
<ul id="appsList">
    <li><span>bb</span> <span class="sort">ios</span></li>
    <li><span>bb</span> <span class="sort">facebook</span></li>
    <li><span>bb</span> <span class="sort">android</span></li>
    <li><span>aa</span> <span class="sort">ios</span></li>
    <li><span>aa</span> <span class="sort">facebook</span></li>
    <li><span>aa</span> <span class="sort">android</span></li>
    <li><span>aa</span> <span class="sort">android01</span></li>
    <li><span>bb</span> <span class="sort">android01</span></li>
    <li><span>aa</span> <span class="sort">android02</span></li>
    <li><span>bb</span> <span class="sort">android02</span></li>
    <li><span>aa</span> <span class="sort">android03</span></li>
    <li><span>bb</span> <span class="sort">android03</span></li>
    <li><span>aa</span> <span class="sort">android04</span></li>
    <li><span>bb</span> <span class="sort">android04</span></li>
    <li><span>aa</span> <span class="sort">android05</span></li>
    <li><span>bb</span> <span class="sort">android05</span></li>
    <li><span>aa</span> <span class="sort">android06</span></li>
    <li><span>bb</span> <span class="sort">android06</span></li>
    <li><span>aa</span> <span class="sort">android07</span></li>
    <li><span>bb</span> <span class="sort">android07</span></li>
    <li><span>aa</span> <span class="sort">android08</span></li>
    <li><span>bb</span> <span class="sort">android08</span></li>
    <li><span>aa</span> <span class="sort">android09</span></li>
    <li><span>bb</span> <span class="sort">android09</span></li>
    <li><span>aa</span> <span class="sort">android10</span></li>
    <li><span>bb</span> <span class="sort">android10</span></li>
    <li><span>aa</span> <span class="sort">android11</span></li>
    <li><span>bb</span> <span class="sort">android11</span></li>
    <li><span>aa</span> <span class="sort">android12</span></li>
    <li><span>bb</span> <span class="sort">android12</span></li>
    <li><span>aa</span> <span class="sort">android13</span></li>
    <li><span>bb</span> <span class="sort">android13</span></li>
    <li><span>aa</span> <span class="sort">android14</span></li>
    <li><span>bb</span> <span class="sort">android14</span></li>
    <li><span>aa</span> <span class="sort">android15</span></li>
    <li><span>bb</span> <span class="sort">android15</span></li>
    <li><span>aa</span> <span class="sort">android16</span></li>
    <li><span>bb</span> <span class="sort">android16</span></li>
    <li><span>aa</span> <span class="sort">android17</span></li>
    <li><span>bb</span> <span class="sort">android17</span></li>
    <li><span>aa</span> <span class="sort">android18</span></li>
    <li><span>bb</span> <span class="sort">android18</span></li>
    <li><span>aa</span> <span class="sort">android19</span></li>
    <li><span>bb</span> <span class="sort">android19</span></li>
    <li><span>aa</span> <span class="sort">android20</span></li>
    <li><span>bb</span> <span class="sort">android20</span></li>
</ul>
After sort :
<ul id="resultAppsList">
</ul>

编辑:这只执行第一次排序,您必须修改sortElements以按.sort对它们进行分组,然后在li span:first-child上再进行一次传递。

我大致使用它按data-*属性对列表进行排序,这是修改后供您使用的代码。使用 jquery 获取元素数组,然后使用 javascript 的原生排序对它们进行排序。这将按字母顺序对它们进行排序。在我的用例中,每个元素都被分配了一个带有数值的data-*属性(该代码位于第一个示例下方)。这是一个jsfiddle。

function sortElements($parent, selector, sortSelector) {
    var elArr = $parent.find(selector).get();
    var sorted = elArr.sort(function (a, b) {
        var aSortOrder = $(a).find(sortSelector).text();
        var bSortOrder = $(b).find(sortSelector).text();
        if (aSortOrder > bSortOrder)
            return 1;
        else if (aSortOrder < bSortOrder)
            return -1;
        else
            return 0;
    });
    $parent.html(sorted);
}

按数字data-*属性排序:

function sortElements($parent, selector, dataAttr) {
    var elArr = $parent.find(selector).get();
    var sorted = elArr.sort(function (a, b) {
        var aSortOrder = parseInt($(a).data(dataAttr), 10);
        var bSortOrder = parseInt($(b).data(dataAttr), 10);
        if (aSortOrder > bSortOrder)
            return 1;
        else if (aSortOrder < bSortOrder)
            return -1;
        else
            return 0;
    });
    $parent.html(sorted);
}

我找到了解决方案:这是我的JS代码

function listElementsWithMyArray(){
    //here you can configure your array
    var myArray = ["ios"];
    //creates all needed variables
    var elements = document.getElementsByClassName("sort");
    var ulelement = document.getElementById("myUL");
    var elementStrings = [];
    var elementStringsInMyArray = [];
    var elementStringsNotInMyArray = [];
    //to fill the list with the values of the spans
    for(var i = 0; i < elements.length; i++){
        var element = elements[i];
        elementStrings.push(element.innerHTML);
    }
    //sort the list and also remove the <li> items
    elementStrings.sort();
    ulelement.innerHTML = "";
    //check if the item is in your array and add to the final arrays
    for(var i = 0; i < elementStrings.length; i++){
        var b = 0;
        if(myArray.indexOf(elementStrings[i]) > -1){
            elementStringsInMyArray.push(elementStrings[i]);
            b = 1;
        }else{
            elementStringsNotInMyArray.push(elementStrings[i]);
        }
    }
    //sort both arrays
    elementStringsInMyArray.sort();
    elementStringsNotInMyArray.sort();
    //list all items from myArray and later on from notMyArray
    for(var i = 0; i < elementStringsInMyArray.length; i++){
        ulelement.innerHTML = ulelement.innerHTML + '<li><span class="sort">' + elementStringsInMyArray[i] + '</class></li>';
    }
    for(var i = 0; i < elementStringsNotInMyArray.length; i++){
        ulelement.innerHTML = ulelement.innerHTML + '<li><span class="sort">' + elementStringsNotInMyArray[i] + '</class></li>';
    }
}

这是我的 HTML 代码

<ul id="myUL">
    <li><span class="sort">android</span>
    <li><span class="sort">facebook</span>
    <li><span class="sort">ios</span>
    <li><span class="sort">android</span>
    <li><span class="sort">facebook</span>
    <li><span class="sort">ios</span>
</ul>

我知道你会喜欢jQuery中的代码,但我在完成后看到了它 - 如果你喜欢我的代码并且你希望我用jQuery重写它,我很好^^

否则我希望它对;)有所帮助

我认为这就是你所追求的。 它首先基于数组中的包含生成排序,然后基于 .sort 跨度,最后基于初始跨度。 结果将追加回显示为就地排序的原始父容器。 此示例从代码中的"未排序"列表开始。

其中很多代码只是注释,您当然可以删除。

// --------------------------
// items in this array will sort ahead of those not in the array
// note: position in the array is not important
// --------------------------
var arr = ["ios"];
// --------------------------
// --------------------------
// the parent container
// used to find children and for re-inserting children in the correct order
// --------------------------
var parent = document.getElementById("appsList");
// --------------------------
// --------------------------
// children to be sorted
// --------------------------
var items = Array.from(parent.querySelectorAll("li"));
// --------------------------
// --------------------------
// sort the children
// --------------------------
items.sort(function(a,b){
  // --------------------------
  // create a string that will be sorted
  // --------------------------
  var _prep = function(item){
    var text1 = item.querySelector("span").innerText;
    var text2 = item.querySelector(".sort").innerText;
    return (arr.indexOf(text2) != -1 ? "a~" : "z~") + text2 + "~" + text1
  };
  // --------------------------
  // --------------------------
  // traditional alpha sort function
  // --------------------------
  var _sortAlpha = function(a, b){
    if( a < b ) return -1;
    if( a > b) return 1;
    return 0;
  };
  // --------------------------
  
  // --------------------------
  // return the alpha sorting of our special strings
  // --------------------------
  return _sortAlpha(_prep(a), _prep(b));
  // --------------------------
});
// --------------------------
// --------------------------
// re-insert the children back into the parent
// effectively an in-place sorting
// --------------------------
items.forEach(function(item){ parent.appendChild(item); });
// --------------------------
<ul id="appsList">
    <li><span>bb</span> <span class="sort">ios</span></li>
    <li><span>bb</span> <span class="sort">facebook</span></li>
    <li><span>bb</span> <span class="sort">android</span></li>
    <li><span>aa</span> <span class="sort">ios</span></li>
    <li><span>aa</span> <span class="sort">facebook</span></li>
    <li><span>aa</span> <span class="sort">android</span></li>
 </ul>