基于自定义数组顺序的 tinysort 排序 div

tinysort sort divs based on custom array order

我目前正在使用 tinysort.js 插件,我想根据数组对一些 div 进行排序。我不确定如何使用 tinysort 解决这个问题。

这是我目前拥有的:

html:

<div id="list">
    <div class="row" data-type="fruit">banana</div>
    <div class="row" data-type="fruit">apple</div>
    <div class="row" data-type="fruit">avocado</div>
    <div class="row" data-type="dairy">milk</div>
    <div class="row" data-type="other">car</div>
    <div class="row" data-type="dairy">cheese</div>
    <div class="row" data-type="grain">rice</div>
    <div class="row" data-type="grain">wheat</div>
    <div class="row" data-type="grain">barley</div>
</div>

javascript:

var $rows = $('#list .row');
var order = ['grain', 'fruit', 'dairy']; // this is the order I'd like the divs to be in

tinysort($rows, {sortFunction:function(a, b) {
    var rowA = $(a.elm).data('type');
    var rowB = $(b.elm).data('type');

    return rowA == rowB ? 0 : (rowA > rowB ? 1 : -1);
}});

我怎样才能应用顺序数组,以便相应地对 div 进行排序?

我相信使用 Array.prototype.indexOf 会奏效:

tinysort($rows, {sortFunction:function(a, b) {
    var rowA = order.indexOf($(a.elm).data('type'));
    var rowB = order.indexOf($(b.elm).data('type'));

    return rowA == rowB ? 0 : (rowA > rowB ? 1 : -1);
}});

如果可以使用对象而不是数组,那么:

var $rows = $('#list .row');

var order = {   // the order is an object that maps types into an integer that represents the precedence (the lower the number the higher the precedence is)
  'grain': 0,
  'fruit': 1,
  'dairy': 2,
  'other': 3
};

tinysort($rows, {sortFunction:function(a, b) {
    var rowA = $(a.elm).data('type');
    var rowB = $(b.elm).data('type');
    
    rowA = order[rowA];  // get the integer representation of this type
    rowB = order[rowB];  // get the integer representation of this type

    return rowA == rowB ? 0 : (rowA > rowB ? 1 : -1); // if the two integers are the same (same precedence) then return 0, otherwise return either 1 or -1 depending on who's should come first using the integer representaion (I think it is self explanatory ;))
}});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinysort/2.3.6/tinysort.min.js"></script>
<div id="list">
    <div class="row" data-type="fruit">banana</div>
    <div class="row" data-type="fruit">apple</div>
    <div class="row" data-type="fruit">avocado</div>
    <div class="row" data-type="dairy">milk</div>
    <div class="row" data-type="other">car</div>
    <div class="row" data-type="dairy">cheese</div>
    <div class="row" data-type="grain">rice</div>
    <div class="row" data-type="grain">wheat</div>
    <div class="row" data-type="grain">barley</div>
</div>

注意如果你仍然想要数组,那么它可以很容易地转换成一个等价的对象:

var orderObject = orderArray.reduce((obj, t, i) => (obj[t] = i, obj), {});

注意 应包括所有类型,否则排序将被破坏,因为整数表示不存在,因此 undefinednumber < undefined undefined < number 总是 false。如果你不想在 order 变量中包含所有类型,你可以做一个测试来检查它是否在排序函数中 undefined