【问题标题】:sort array of divs based on types of divs from low to high in javascript/jquery根据 javascript/jquery 中从低到高的 div 类型对 div 数组进行排序
【发布时间】:2017-09-19 08:27:54
【问题描述】:

以下代码用于对数组进行排序,如下所示:

function sorter(a, b) {
    if((b.dataset.type === 'Recommended') && (a.dataset.type === 'Recommended'))
      return (b.dataset.type === 'Recommended') - (a.dataset.type === 'Recommended') || a.dataset.amount - b.dataset.amount;
    if((b.dataset.type === 'Featured') && (a.dataset.type === 'Featured'))
        return (b.dataset.type === 'Featured') - (a.dataset.type === 'Featured') || a.dataset.amount - b.dataset.amount;
    if((b.dataset.type === 'Special Offer') && (a.dataset.type === 'Special Offer'))
        return (b.dataset.type === 'Special Offer') - (a.dataset.type === 'Special Offer') || a.dataset.amount - b.dataset.amount;
    if((b.dataset.type === 'Christmas') && (a.dataset.type === 'Christmas'))
        return (b.dataset.type === 'Christmas') - (a.dataset.type === 'Christmas') || a.dataset.amount - b.dataset.amount;
    if((b.dataset.type === '') && (a.dataset.type === ''))
        return (b.dataset.type === '') - (a.dataset.type === '') || a.dataset.amount - b.dataset.amount;
  }
  var sortedDivs = $(".terminalpopular").toArray().sort(sorter);

我已经根据 div 上标记的不同类型(即推荐、精选、圣诞节和无类型)对数组进行了排序,如下所示:

<div class=​"terminalpopular" data-amount=​"65.95" data-type=​"Recommended">​…​</div>​
<div class=​"terminalpopular" data-amount=​"70" data-type=​"Recommended">​…​</div>​
<div class=​"terminalpopular" data-amount=​"94.95" data-type=​"Recommended">​…​</div>​
<div class=​"terminalpopular" data-amount=​"67.99" data-type=​"Featured">​…​</div>​
<div class=​"terminalpopular" data-amount=​"75" data-type=​"Featured">​…​</div>​
<div class=​"terminalpopular" data-amount=​"78" data-type=​"Christmas">​…​</div>​
<div class=​"terminalpopular" data-amount=​"84.99" data-type=​"Christmas">​…​</div>​
<div class=​"terminalpopular" data-amount=​"54.95" data-type>​…​</div>​
<div class=​"terminalpopular" data-amount=​"84.99" data-type>​…​</div>​

我想按以下方式对其进行排序(预期结果):

<div class=​"terminalpopular" data-amount=​"65.95" data-type=​"Recommended">​…​</div>​
<div class=​"terminalpopular" data-amount=​"67.99" data-type=​"Featured">​…​</div>​
<div class=​"terminalpopular" data-amount=​"78" data-type=​"Christmas">​…​</div>​
<div class=​"terminalpopular" data-amount=​"70" data-type=​"Recommended">​…​</div>
<div class=​"terminalpopular" data-amount=​"75" data-type=​"Featured">​…​</div>​
<div class=​"terminalpopular" data-amount=​"84.99" data-type=​"Christmas">​…​</div>​​
<div class=​"terminalpopular" data-amount=​"94.95" data-type=​"Recommended">​…​</div>​
<div class=​"terminalpopular" data-amount=​"54.95" data-type>​…​</div>​
<div class=​"terminalpopular" data-amount=​"84.99" data-type>​…​</div>​

文字演示:

您能否建议我如何以这种方式根据类型对数组进行排序。即推荐的值为84、74、64,我们也有特征类型,其值为78、68、88。我们可以按以下形式对其进行排序:64(推荐)、68(推荐)、74(推荐), 78(精选)、84(推荐)、88(精选)等等等等?

【问题讨论】:

  • 所以要根据数据量对列表进行排序?
  • 如果你想要一个可以随便扔的库,listjs.com 很不错
  • 实际上,我想按价格从低到高对每种类型的 div(即推荐、精选、特价、圣诞节和无类型)进行排序。推荐具有更高的优先级,其次是其他类型。即它应该在推荐中显示 LOW,然后是精选的 LOW 价格,然后是特别优惠的 LOW 价格(如果有),然后是圣诞节的 LOW 值,最后是无类型 div 的 LOW 到 HIGH。我希望,你明白了。
  • Recommended 优先级更高,其次是其他类型 如果是这样,94.95 是否应该排在第二位?
  • 它就像:个别类型的 LOW 到 HIGH。从第一组中取第一个低点,即推荐,你就完成了。现在,在特色中检查 LOW,你就完成了。现在,检查,特别优惠中的 LOW,你就完成了,检查,圣诞节的 LOW,你就完成了,等等。现在,再次检查 2nd Recommended LOW 值,依此类推...... . . . .

标签: javascript jquery html arrays sorting


【解决方案1】:

以下是您想要的安排的示例。

据我了解,在这里使用 1 排序功能会很困难,因此分阶段解决了问题。因此,以下解决方案可能需要多次额外迭代。

var emptyList = '__EMPTY__';
function processElements() {
  var list = $('.terminalpopular');
  var clone = list.clone();
  
  var groupedList = createGroups(clone);
  var sortedGroups = sortGroups(groupedList);
  var arrangedList = arrangeElements(sortedGroups);
  
  list.parent().empty().append(arrangedList)
}

// Create groups based on type
function createGroups(list) {
  return Array.from(list).reduce(function(p, c){
    var type = c.dataset.type || emptyList;
    p[type] = p[type] || [];
    p[type].push(c);
    return p;
  }, Object.create(null));
}

// Sort each group by amount
function sortGroups(list) {
  function sortFn(a, b) {
    return Number(a.dataset.amount) - Number(b.dataset.amount);
  }
  for (var k in list) {
    list[k].sort(sortFn);
  }
  return list;
}

// Rearrange elements based on index
function arrangeElements(sortedList) {
  var list = [];
  var max = Math.max.apply(null, Object.keys(sortedList)
              .filter(x => x !== emptyList)
              .map(x => sortedList[x].length)
            );
  for(var i = 0; i< max; i++) {
    list = list.concat(Object.keys(sortedList)
              .filter(x => x !== emptyList)
              .map(x => sortedList[x][i])
            );
  }           
  
  list = list.concat(sortedList[emptyList]);
  return list;
}

// This is only for display purpose
function displayValue() {
  $('.terminalpopular').each(function(i, el) {
    $(el).text($(el).data('amount'));
    if ($(el).data('type')) {
      $(el).addClass('highlight')
    }
  })
}

displayValue();
processElements();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div>
  <div class="terminalpopular" data-amount="65.95" data-type="Recommended">​…​</div>​
  <div class="terminalpopular" data-amount="70" data-type="Recommended">​…​</div>​
  <div class="terminalpopular" data-amount="94.95" data-type="Recommended">​…​</div>​
  <div class="terminalpopular" data-amount="67.99" data-type="Featured">​…​</div>​
  <div class="terminalpopular" data-amount="75" data-type="Featured">​…​</div>​
  <div class="terminalpopular" data-amount="78" data-type="Christmas">​…​</div>​
  <div class="terminalpopular" data-amount="84.99" data-type="Christmas">​…​</div>​
  <div class="terminalpopular" data-amount="54.95" data-type>​…​</div>​
  <div class="terminalpopular" data-amount="84.99" data-type>​…​</div>​
</div>

【讨论】:

  • ​...​
    ​.圣诞节应该排在第三位。请检查我在问题中给出的预期结果。
  • 预期结果:===============数据量=“65.95”数据类型=“推荐”(推荐:第一低)数据- amount="67.99" data-type="Featured" (feat: 1st low) data-amount="78" data-type="Christmas" (christ: 1st low) data-amount="70" data-type="推荐" (推荐: 2nd low) data-amount="75" data-type="Featured" (feat: 2nd low) data-amount="84.99" data-type=​" Christmas" (christ: 2nd low) data-amount="94.95" data-type="Recommended" (recom: 3th low) data-amount="54.95" data-type (noType: 1st low) data-amount =​“84.99”数据类型(noType:第二低)
  • 是的,根据类型考虑组,并从每个组中获取第一个 LOW 值并附加;末尾没有类型,从 LOW 到 HIGH。
  • 如果你能同时关注给定的 Div 和预期的结果 Div,你就会明白整个想法。谢谢
  • 谢谢,我也查过了。干得漂亮,完成了。谢谢拉杰什。你太棒了。
【解决方案2】:

您可以使用sort()方法,先按数据type属性排序,再按amount

var sorted = $(".parent > div").sort(function(a, b) {
  return ($(b).data('type') != '') - ($(a).data('type') != '') || +$(a).data('amount') - +$(b).data('amount')
})

$('.parent').html(sorted)

// Just for demo
$('.parent > div').each(function() {
  $(this).text($(this).data('amount'))
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
  <div class="terminalpopular" data-amount="65.95" data-type="Recommended">…</div>
  <div class="terminalpopular" data-amount="70" data-type="Recommended">…</div>
  <div class="terminalpopular" data-amount="94.95" data-type="Recommended">…</div>
  <div class="terminalpopular" data-amount="67.99" data-type="Featured">…</div>
  <div class="terminalpopular" data-amount="75" data-type="Featured">…</div>
  <div class="terminalpopular" data-amount="78" data-type="Christmas">…</div>
  <div class="terminalpopular" data-amount="84.99" data-type="Christmas">…</div>
  <div class="terminalpopular" data-amount="54.95" data-type>…</div>
  <div class="terminalpopular" data-amount="84.99" data-type>…</div>
</div>

更新使用基于类型的键和值作为具有这些类型的元素数组创建对象,然后根据数量对这些值进行排序,然后循环每个对象属性并添加到父元素。

var obj = {}
$('.parent > div').each(function() {
  var type = $(this).data('type');
  if (type == '') type = 'empty';
  if (!obj[type]) obj[type] = [];
  obj[type].push($(this))
})

for (var i in obj) obj[i].sort(function(a, b) {
  return $(a).data('amount') - $(b).data('amount')
})

$('.parent').empty();
var max = Object.keys(obj).reduce(function(r, e) {
  var l = obj[e].length;
  if (r == null || l > obj[r].length) r = e
  return r;
}, null)

obj[max].forEach(function(e, i) {
  Object.keys(obj).forEach(function(k) {
    if (k != 'empty' && obj[k][i]) $('.parent').append(obj[k][i])
  })
})

$('.parent').append(...obj['empty'])

$('.parent > div').each(function() {
  $(this).text($(this).data('amount') + ' ' + $(this).data('type'))
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
  <div class="terminalpopular" data-amount="65.95" data-type="Recommended">…</div>
  <div class="terminalpopular" data-amount="70" data-type="Recommended">…</div>
  <div class="terminalpopular" data-amount="94.95" data-type="Recommended">…</div>
  <div class="terminalpopular" data-amount="67.99" data-type="Featured">…</div>
  <div class="terminalpopular" data-amount="75" data-type="Featured">…</div>
  <div class="terminalpopular" data-amount="78" data-type="Christmas">…</div>
  <div class="terminalpopular" data-amount="84.99" data-type="Christmas">…</div>
  <div class="terminalpopular" data-amount="54.95" data-type>…</div>
  <div class="terminalpopular" data-amount="84.99" data-type>…</div>
</div>

【讨论】:

  • ​...​
    ​.圣诞节应该排在第三位。请检查我在问题中给出的预期结果。
  • 预期结果:===============数据量=“65.95”数据类型=“推荐”(推荐:第一低)数据- amount="67.99" data-type="Featured" (feat: 1st low) data-amount="78" data-type="Christmas" (christ: 1st low) data-amount="70" data-type="推荐" (推荐: 2nd low) data-amount="75" data-type="精选" (feat: 2nd low) data-amount="84.99" data-type=​" Christmas" (christ: 2nd low) data-amount="94.95" data-type="Recommended" (recom: 3th low) data-amount="54.95" data-type (noType: 1st low) data-amount =​“84.99”数据类型(noType:第二低)
  • 太棒了。谢谢。我正在对我拥有的所有组进行尝试,并相应地更新我的代码。
  • 谢谢。它就像一个魅力。我扩展了它并根据我的需要制作它。你很棒。谢谢老兄。
猜你喜欢
  • 1970-01-01
  • 2018-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-01
  • 2011-09-02
  • 1970-01-01
  • 2011-01-22
相关资源
最近更新 更多