Марк строк с одинаковыми значениями в таблице


У меня есть простой алгоритм, который помечает строки таблицы с одинаковыми значениями синий. Проблема в том, что это решение требует много времени.

Кто-нибудь идея, как улучшить скорость этого?

$(document).ready(function(){
   var tableRows = $("#sortable tbody tr");
   tableRows.each(function(n){
      var id = $(this).attr('id'); 
      var example = $(this).children('#example').children('#content').html(); 

      tableRows.each(function(n){
         if($(this).attr('id') != id)
         {
            if ($(this).children('#example').children('#content').html() == example)
            {
               $(this).css('backgroundColor', 'azure');
            }
         }
      });
   });
});

Моя таблица выглядит так:

<table align="center" id="sortable">
   <thead>
      <tr bgcolor="orange">
         <th>Digitcode</th>
      </tr>
   </thead>

   <tbody>
      <tr id="1">
         <th id="example" class="data"><div contenteditable id="content">test</div></th>
      </tr>
   </tbody>
</table>


25656
17
задан 2 декабря 2011 в 02:12 Источник Поделиться
Комментарии
4 ответа

В ВАР $rowsToMark = $(); не работает. Ничего не было отмечено.

Теперь я сравниваю всех строк, а не все столбцы внутри них.

Время загрузки моего сайта теперь составляет 1,5 секунды. Раньше это было 5,5 секунд.

$(document).ready(function() {
var tableRows = $("#sortable tbody tr");

tableRows.each(function(n){
var id = this.id;
var row = $(this).html();

tableRows.each(function(n){
var $this;

if(this.id != id){
$this = $(this);

if ($this.html() == row){
$this.css('backgroundColor', 'azure');
}
}
});
});
});

1
ответ дан 6 декабря 2011 в 09:12 Источник Поделиться

Без составления алгоритмических изменений, мы все еще можем сделать некоторые улучшения производительности:

$(document).ready(function() {
var $tableRows = $("#sortable tbody tr");
var $rowsToMark = $();

$tableRows.each(function(n) {
var id = this.id;
var example = $(this).find('.content').html();

$tableRows.each(function(n) {
var $this;
if (this.id != id) {
$this = $(this);
if ($this.find('.content').html() == example) {
$rowsToMark.add($this);
}
}
});
});

$rowsToMark.css('backgroundColor', 'azure');
});


Если вы действительно хотите начать оптимизацию (я серьезно сомневаюсь, что оно того стоит, правда) можно взять динамическое программирование подход и сделать некоторые кэширования. Например:


  • Вы действительно не нужно звонить .HTML-код() на любой заданной строке более одного раза. Начнем с HTML-код каждой строки и сохранить его, то можно сравнить с помощью перебора этих строк в HTML скорее, чем к элементам DOM.

  • Если вы уже определили, что строки A и B равны, вам нужно лишь сравнить строку с против А или Б.

  • (другие вещи, которые я еще не думала)


Общая производительность с jQuery/информационный оптимизации:

6
ответ дан 2 декабря 2011 в 02:12 Источник Поделиться

Алгоритм от вопроса будет выполнять в раз из N^2, где N равно числу строк. Лучшим решением будет просто во Времени N (т. е. итерации только на строках раз). Это решение требует пожертвовать немного памяти для хранения после каждого значения строки.

Таким образом, учитывая таблицу типа:

<table id="sortable">
<tbody>
<tr>
<td class="content">A</td>
</tr>
<tr>
<td class="content">B</td>
</tr>
<tr>
<td class="content">A</td>
</tr>
</tbody>
</table>

затем в JavaScript, как в следующем будет отмечаться соответствующих строк за один проход:

$(function() {
var tableRows = $("#sortable tbody tr"); //find all the rows
var rowValues = []; //to keep track of which values appear more than once
tableRows.each(function() {
var rowValue = $(this).find(".content").html();
if (!rowValues[rowValue]) {
var rowComposite = new Object();
rowComposite.count = 1;
rowComposite.row = this;
rowValues[rowValue] = rowComposite;
} else {
var rowComposite = rowValues[rowValue];
if (rowComposite.count == 1) {
$(rowComposite.row).css('backgroundColor', 'azure');
}
$(this).css('backgroundColor', 'azure');
rowComposite.count++;
}
});
});

5
ответ дан 2 декабря 2011 в 05:12 Источник Поделиться

1,5 секунды на ~1000 строк по-прежнему кажется очень высокой для меня. Ваш алгоритм является o(п^2).

Мы можем сделать как лучше.

$(document).ready(function() {
var tableRows = $("#sortable tbody tr"),
// we know exactly how large to make it, so don't use []
htmlStrings = new Array(tableRows.length),
i, j, current, comparing;

for (i = 0; i < tableRows.length; i++) {
current = htmlStrings[i];
// get each innerHTML just once
if (!current) {
current = {
html: tableRows.get(i).innerHTML,
isDup: false
};
htmlStrings[i] = current;
}

// if we already know it's a dup, so we're done
if (current.isDup) continue;

// start j at i+1 since we've already looked at the previous i rows
for (j = i + 1; j < tableRows.length; j++) {
// could stay DRY and put this into a function;
// doing so may decrease performance (not benchmarked)
comparing = htmlStrings[j];
if (!comparing) {
comparing = {
html: tableRows.get(j).innerHTML,
isDup: false
};
htmlStrings[j] = comparing;
}

if (comparing.isDup) continue;

// It comes to this: we must actually compare now.
if (current.html === comparing.html) {
current.isDup = true;
comparing.isDup = true;

// mark it
tableRows.eq(j).css('backgroundColor', 'red');
}
}

if (current.isDup) {
// mark it
tableRows.eq(i).css('backgroundColor', 'red');
}

}
});​


  1. Не звони .HTML-код() на любую одну строку более одного раза.

  2. Если строка уже отмечен как дубликат, нет никаких причин, чтобы в дальнейшем обрабатывать его, ни какой-либо из рядов, - это повторение.

  3. При взгляде на п- й строки, мы уже смотрели на все предыдущие Н-1 строк, так что нет никаких оснований смотреть на этих, либо.

  4. Использовать регулярно в течение цикла, а не по каждому элементу , которые принимает функция.

  5. Использовать .innerHTML будет скорее, чем .HTML-код().

  6. Использовать === , а не ==.

Для тестирования производительности, я собираюсь предположить, что текст каждой строки-это случайное целое число ∈ [0, 9999]. Это позволяет легко генерировать большое количество случайных строк, которые имеют разумную вероятность столкновения:

var arr = [];
for (var i=0; i<1000; i++)
{
arr.push('<tr id="' + i + '"><th class="data"><div contenteditable>' + (~~(Math.random()*10000)) + '</div></th></tr>');
}
console.log(arr.join('\n'));

Оригинальный ответ это код, О(N^2): jsFiddle

Оптимизирован, за o(n записей N), я думаю: jsFiddle

см. Этот тест jsperf сравнения: 1к строк | 10к строк

Посмотрите, насколько быстрее это!

2
ответ дан 18 марта 2012 в 09:03 Источник Поделиться