How to compare cells in JavaScript table to each other and test for equality? How does indexOf work?

懵懂的女人 提交于 2019-12-01 01:53:02

You can use the table rows and cells collections for the iteration. The following does a literal comparison of the text content, you may wish to process the text first to "normalise" it in regard to whitespace.

<table id="t0">
 <tr><td>foo<td>bar<td>fum</td>
 <tr><td>fum<td>bar<td>foo</td>
 <tr><td>foo<td>fum<td>fum</td>
</table>

<script>

compareRows(document.getElementById('t0'));

function compareRows(table) {
  var row, rows = table.rows;
  var cell, cells;
  var rowText;

  // For each row in the table
  for (var i=0, iLen=rows.length; i<iLen; i++) {
    row = rows[i];
    cells = row.cells;

    // Compare the text in each cell
    for (var j=0, jLen=cells.length; j<jLen; j++) {
      cell = cells[j];

      for (var k=0; k<jLen; k++)

        if (k != j && cells[k].textContent == cell.textContent) {
          // cell text is repeated in current row
          console.log('row ' + i + ' cell ' + j + ' text repeated in cell ' + k);
      }

      // Compare with the text in the cell immediately below (if there is one)
      if (i < iLen-2 && cell.textContent == rows[i+1].cells[j].textContent) {
        // cell text is repeated in next row
        console.log('row ' + i + ' cell ' + j + ' text repeated in row ' + (i+1));
      }
    }
  }
}
</script>

Note that repeated text in a row will be reported twice.

The above uses the textContent property, which may be supported as innerText in some user agents. It also runs about 10 times faster than the jQuery alternative.

You should get an array of rows, each row is an array of cells. That way the validation is much easier. I'm not sure about how you want to show the conflict. In this demo I've just highlight the duplicated cells (conflicted) in red (at least I like this kind of showing conflict rather than modifying the conflicted cells' text).

HTML:

<table>
  <tr><td>1</td><td>2</td><td>3</td></tr>
  <tr><td>1</td><td>5</td><td>6</td></tr>
  <tr><td>7</td><td>8</td><td>7</td></tr>
  <tr><td>8</td><td>9</td><td>10</td></tr>
</table>
<button>Check constraints</button>

CSS:

td {
  width:100px;
  height:50px;
  border:1px solid black;
}
table {
  border:1px solid black;
  border-collapse:collapse;
}
td.invalid {
  background:red;
}

JS:

$('td').attr('contenteditable',true);
var cell;     
function highlight(){    
  $(arguments).toggleClass('invalid',true);
}
function checkConstraints(e){
  //reset style before re-checking
  $('td.invalid').toggleClass('invalid');
  //get rows as an array of array
  var rows = $('tr').map(function(elem,i){
      return [$(this).children('td').toArray()];
  }).toArray();        
  //loop through the rows
  for(var i = 0; i < rows.length; i++){
    cell = {};        
    for(var j = 0; j < rows[i].length; j++){
        var cellText = $(rows[i][j]).text();
        if(cell[cellText]) {  
            highlight(cell[cellText], rows[i][j]);                
        } else {
            cell[cellText] = rows[i][j];
        }
        if(i < rows.length - 1 && 
           cellText == $(rows[i+1][j]).text()){
           highlight(rows[i][j],rows[i+1][j]);
        }            
    }        
  }
}
$('button').click(checkConstraints);

Demo.

Note that, I set contenteditable for all the cells (td), you can edit the cells text to what you want and click the button to test the demo.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!