jQuery按等级(desc)排序并根据值隐藏div

Posted

技术标签:

【中文标题】jQuery按等级(desc)排序并根据值隐藏div【英文标题】:jQuery sort by rating (desc) and hide divs based on value 【发布时间】:2010-11-27 04:18:24 【问题描述】:

我正在努力实现以下目标。我有十几个 div,例如:

    <div id=1><div>test 1</div><div>4</div></div>
<div id=2><div>test2</div><div>1</div></div>
<div id=3><div>test3</div><div>6</div></div>
<div id=4><div>test4</div><div>3</div></div>
<div id=5><div>test5</div><div>2</div></div>
<div id=6><div>test6</div><div>0</div></div>
<div id=7><div>test7</div><div>3</div></div>
 ...

现在我想使用 jQuery 仅显示前 5 个 div,即评级为 4、6、3、2、3 按此顺序 并隐藏其余部分。

知道该怎么做吗?我宁愿不使用任何额外的插件等。

【问题讨论】:

您是否只想显示前 5 名而不管其内容是什么?或者您想根据他们的内容显示前 5 个 他们当然会有不同的内容。但根据收视率,我想隐藏所有不是前 5 的 div。请注意,前 5 并不意味着前 5。 它们不会以任何方式排序?就像您现在正在显示它们一样:4、2、6、4、1、1、0。如果有一个内容为 7 的 8 个 div,那么该 div 是否也需要显示?有意义吗? 是的,对...抱歉,如果我的问题不太清楚。 它应该基本隐藏其余不是前 5 名的评分。 【参考方案1】:

为您的 html 提供更多结构,以便您可以将其与选择器一起使用:

<div class="song">
    <div>4</div>
</div>
<div class="song">
    <div>2</div>
</div>
<div class="song">
    <div>6</div>
</div>
<div class="song">
    <div>3</div>
</div>
<div class="song">
    <div>1</div>
</div>
<div class="song">
    <div>1</div>
</div>
<div class="song">
    <div>0</div>
</div>

O(n*logn)

allSongs = $("div.song").get();
allSongs.sort(function(a,b) 
    a = $(a);
    b = $(b);
    // calling a.text() does only work if there's no text besides the rating.
    if (a.text() > b.text()) 
        return -1;
     else if (a.text() < b.text()) 
        return 1;
     else 
        return 0;
    
);

// hide all elements that have an index greater/equal to 5
$(allSongs.slice(5)).hide();

O(n*m)

songs = $("div.song").get();
for (var i = 0; i < 5; i++) 
    var indexOfTop = -1;
    var topRating = -1;
    // find best rated song
    jQuery.each(songs, function(j) 
        // this line needs to be adapted for your code
        var rating = $(this).text();
        if (rating > topRating) 
            topRating = rating;
            indexOfTop = j;
        
    ); 
    // remove top item from array
    if (indexOfTop == -1) 
        // no items left in songs
        return false;
     else 
        songs.splice(indexOfTop, 1);
    


// remove remaining songs
$(songs).hide();

O(m*logn)

function BinaryHeap(keyFunction)  
    if (arguments.length >= 1)  
        this.keyFunction = keyFunction; 
     
    this.content = []; 
 

BinaryHeap.buildHeap = function(items, keyFunction)  
    var newHeap = new BinaryHeap(); 
    if (arguments.length >= 2)  
        this.keyFunction = keyFunction; 
     
    // slice copies the array 
    newHeap.content = items.slice(0); 
    var firstParent = Math.floor((newHeap.content.length - 1) / 2); 
    for (var i = firstParent; i >= 0; i--)  
        newHeap._siftDown(i); 
     
    return newHeap; 
 

BinaryHeap.prototype =  
    push: function(item)  
        this.content.push(item) 
        this._siftUp(this.content.length - 1); 
    , 
    pop: function()  
        var value = this.content[0]; 
        var newHead = this.content.pop(); 
        if (this.content.length >= 1)  
            this.content[0] = newHead; 
            this._siftDown(0); 
         

        return value; 
    , 
    // default key function, it extracts a key from the object 
    keyFunction: function(a)  
        return a; 
    , 
    _siftDown: function(root)  
        var length = this.content.length; 
        var k = 0; 
        while (root * 2 + 1 < length)  
            k++; 
            var child = root * 2 + 1; 
            var rightChild = root * 2 + 2; 
            if (rightChild < length)  
                child = this._max(child, rightChild); 
             

            if (this._max(root, child) == child)  
                this._swap(root, child); 
             else  
                break; 
             
            root = child; 
         
    , 
    _siftUp: function(child)  
        while (child >= 0)  
            var root = Math.floor((child - 1) / 2); 
            if (this._max(child, root) == root)  
                this._swap(child, root); 
             else  
                return; 
             
            child = root; 
         
    , 
    _max: function(a, b)  
        return (this.keyFunction(this.content[a]) >= this.keyFunction(this.content[b])) ? a : b; 
    , 
    _swap: function(a, b)  
        var buffer = this.content[a]; 
        this.content[a] = this.content[b]; 
        this.content[b] = buffer; 
     
 

allSongs = $("div.song"); 
// build heap in O(n) 
var myheap = BinaryHeap.buildHeap(allSongs.get(), function(item)  
    return $(item).text(); 
); 

// hide all items 
allSongs.hide(); 

// show top 5 
for (var i = 0; i < 5; i++)  
    var item = myheap.pop(); 
    // less than 5 elements 
    if (typeof(item) == "undefined") 
        break; 
    $(item).show(); 

O(n)

绝对不可能。

Timed results

以毫秒为单位的结果 (Mac OS X 10.6、Safari 4.0.3、2.4 Ghz Intel Core 2 Duo) -------- 10个元素 n*登录:3 m*n: 2 米*登录:2 100 个元素 n*登录:26 m*n: 11 米*登录:5 1000 个元素 n*登录:505 男*女:140 米*登录:42 10000 个元素 n*登录:8016 男*女:1648 米*登录:442

【讨论】:

根据我的要求对其进行了调整。工作起来很像一个魅力。如果我有任何问题会告诉你...非常感谢...有什么比这更有效的吗? sorry... done.... 会接受这个作为答案...想知道这是否可以更有效地完成? 我刚刚添加了一个 O(n*m) 方法,但请注意,对于小型数据集,内置的 sort() 方法可能更快。 使用堆,您可以创建一个解决方案 O(m*logn),这是您可以获得的最佳运行时。 非常全面。非常感谢您。我一直认为堆排序仅用于学术目的:)【参考方案2】:

这是我编造的一个快速破解,所以如果导致死亡,我不承担任何责任......

var divs = $('div[id] div:contains("test") + div').get();

divs = divs.sort(function( a, b ) 
  return ( parseInt( b.textContent, 10 ) || -1 ) - ( parseInt( a.textContent, 10 ) || -1 );
).slice(5);

$( divs ).hide();

但我同意更多的 HTML 结构肯定会让你的工作更轻松...

【讨论】:

以上是关于jQuery按等级(desc)排序并根据值隐藏div的主要内容,如果未能解决你的问题,请参考以下文章

msSQL 根据2个条件进行重新排序并增加一个排序字段

sql按某个字段值顺序排序

sql 按字段指定值排序

Jquery DataTables在排序时将顺序更改为desc

MySql操作「数据查询条件20211223

Symfony按特定字段的内容顺序排列