1

js+jQuery を使用して関数を作成しました。

ここに私の問題を示すjsFiddleへのリンクがあります:http://jsfiddle.net/anarnold/LpBaW/

この関数の目的は、テーブルをスキャンし、特定のフィールド (td) 値が一致する行をチェックすることです。次に、行が一意であるかどうかを示すクラスが行に割り当てられ、一致する行の数が各行の最終フィールド (td) に出力されます。

基本的に、この構造のネストされたループを使用します。

行ごとに...テーブル全体をスキャンして一致するものを探します..

行を識別する方法は、各行のフィールド (td) テキストを各行の最終フィールド (td) の rowid 属性に連結することです。

現在の関数は正常に動作しますが、2000 行までの大きなテーブルでは非常に遅くなります。

これを達成するためのより効率的で洗練された方法が必要です。どんな助けでも大歓迎です!

4

6 に答える 6

2

連想配列を使用して結果を保存し、それを反復する例を次に示します。

http://jsfiddle.net/AdDMk/

var rowIdCnt = {};

function unqOrMsgTest() {
    // Store counts here
    var rowIdCnt = {};

    // loop through check tds
    $("#binning tr td[col=check]").each(function() {

        // grab row identifer to check against other rows        
        var rowId = $(this).attr("rowid");

        if (rowId in rowIdCnt) {
            rowIdCnt[rowId] ++;
        } else {
            rowIdCnt[rowId] = 1;
        }

    });

    // Now iterate over each count and update the table appropriately:
    $.each(rowIdCnt, function(rowId, cnt) {
        //this bit of logic picks a class to assign rows        
        var resultClass = "notUnique";
        if (cnt < 2) {
            resultClass = "unique";
        }

        //apply the row class and print the redundancy number into td
        $('#binning tr td[rowid='+rowId+']').text(cnt).parent().addClass(resultClass);

    });

}
于 2012-04-06T22:09:12.247 に答える
1

これを行うためのより良いプリフォーム方法を次に示します。可能な限り冗長な DOM 呼び出しを削除し、無効な属性を修正しました (HTML タグは特定の属性のみをサポートできます。カスタム属性には接頭辞を付ける必要がありますdata-) 。

$(document).ready(function(){ //this is just to fire the function
    $("#unqOrMsgTestFire").click(function(){
        unqOrMsgTest();
    });
});

function check_unique(row, collection) {
    var unique = true, rowid = $(row).children('td[data-col=check]')[0].getAttribute('data-rowid');
    collection.each(function() {
        if( $(this).children('td[data-col=check]')[0].getAttribute('data-rowid') == rowid ) {
            unique = false; 
        }
    });
    return unique;
}

function unqOrMsgTest() { 

    var collection = $("#binning tbody").children('tr');

    collection.each(function(i, el){
        el.className += check_unique( el, collection.not(el) ) ? ' unique' : 'notUnique';
    });            

}​

http://jsfiddle.net/rlemon/LpBaW/41/ <-それらはすべて失敗しますが、それは予想されることです。

于 2012-04-06T22:14:02.383 に答える
0

各テーブル エントリのハッシュ値を作成し、重複をチェックする前にハッシュ テーブルを使用するか、それらを並べ替えます。これにより、隣人を比較するだけで済みます。

于 2012-04-06T21:49:37.940 に答える
0

より洗練された方法は、このテーブルを作成する前にデータ レベルでこれを行うことです。

于 2012-04-06T21:53:29.557 に答える
0

これが私の推奨される解決策です:

http://jsfiddle.net/j9RXR/29/

function unqOrMsgTest() { 
    var rows = $("#binning tbody").children('tr');
    var totalRows = rows.length;
    var idLookup = {};
    var i, rowId, resultClass, checkColumn, rowCount, row;

    // loops through all rows, convert to jQuery objects and track the IDs
    for (i = 0; i < totalRows; i++)
    {
        row = $(rows[i]);
        rowId = row.children('td[col="check"]').attr("rowid");
        rows[i] = row;

        idLookup[rowId] = (rowId in idLookup) ? idLookup[rowId] + 1 : 1;
    }

    // loop through each row and check them for redundancy
    for (var i = 0; i < totalRows; i++ )
    {
        // grab row identifer to check against the id lookup
        row = rows[i];
        checkColumn = row.children('td[col="check"]');
        rowId = checkColumn.attr("rowid");     

        //this bit of logic picks a class to assign rows        
        rowCount = idLookup[rowId];
        resultClass = rowCount < 2 ? "unique" : "notUnique";

        //apply the row class and print the redundancy number into td
        checkColumn.text(rowCount);
        row.attr("class", resultClass);        
    };            
}​

連想配列 (またはハッシュ) を使用して ID とカウントを格納することを提案する上記の回答と同様に、list.each( function() {...} )dom 要素から jQuery オブジェクトへのすべての呼び出しを削除し、変換の数を最小限に抑えました。

の使用を削除した理由eachは、反復ごとに新しい無名関数が作成され、スタックのスラッシングは言うまでもなく、 this から $(this) への冗長な変換も呼び出されたためです。シンプルな for ループだけで十分であり、はるかに高速です。

jQuery の落とし穴の詳細については、避けるべき jQuery の落とし穴を参照してください。

于 2012-04-06T22:33:23.827 に答える
0

http://jsfiddle.net/LpBaW/57/

$(function(){ //this is just to fire the function
    $("#unqOrMsgTestFire").click(unqOrMsgTest);
    $("#spawn").click(function(){
        var blueprint = $("#binning tbody tr").first();
        for(var i = 0; i < 1000; i++)
            blueprint.clone().appendTo("#binning tbody").find('td[rowid]').attr('rowid', Math.floor(Math.random()*500));
    });
});

function unqOrMsgTest() {
    console.profile();
    var toCheck = $("#binning > tbody > tr > td[col=check]"),
        ignore = {},
        curId,
        currentlyProcessing,
        rowsAmount,
        i;

    i = toCheck.length - 1;
    while( i >= 0 ) {
        curId = toCheck.eq(i).attr("rowid");
        if( !(curId in ignore) ) {
            ignore[curId] = undefined;

            currentlyProcessing = $("#binning > tbody > tr > td[rowid=" + curId  + "]");

            rowsAmount = currentlyProcessing.length;

            currentlyProcessing
                .text( rowsAmount )
                .parent().attr('class', rowsAmount > 1 ? "notUnique" : "unique");
        }
        i--;
    }
    console.profileEnd();
}​

        rowsAmount = currentlyProcessing.length;

        currentlyProcessing
            .text( rowsAmount )
            .parent().attr('class', rowsAmount > 1 ? "notUnique" : "unique");

        toCheck = toCheck.not( currentlyProcessing );
    }
}
于 2012-04-06T23:02:39.647 に答える