如何比较单元格在JavaScript表彼此和测试的平等?indexOf是如何工作的

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

本文关键字:工作 何工作 测试 indexOf 单元格 比较 何比较 JavaScript      更新时间:2023-09-26

我在HTML代码中创建了一个表。它有9列13行。它完全被一个JavaScript循环填满,这个循环用几个数组中的人名填充它。但是,我想添加一个验证步骤,以确保行中没有两个单元格具有相同的值,并且每个单元格的值不会在其直接下方的单元格中重复。

由于我只能作为NodeList访问表中单元格的值,因此我决定将其变成一个数组,以便使用IndexOf属性在数组中进行搜索:

var table1 = document.getElementsByTagName("td");
var table1Array = [];    //number of "td" elements on page
for (i = 0; i < 117; i++) {
    table1Array[i] = table1[i].innerHTML;
}

我不知道有比这更优雅的方法了(算是初学者)。因此,我设置了一些嵌套循环,将每个单元格与我创建的行数组中的每个元素进行比较(对于所有13行):

function validateCells() {
for (i = 0; i < 117; i = i + 9) { //increment for going to next column (after 9 cells or elements in array)
    for (j = 0; j < 8; j++) {
        var curCell = table1Array[i];
        var curRow = [];         //I'm ignoring the first column which is "date", so it has 8 elements rather than 9
        for (k = 0; k < 8; k++) {
            curRow[k] = document.getElementById("row" + j).children[k].innerHTML;
        }
        if (curRow.indexOf(curCell) != -1) {
            curCell = "CONFLICT"; //trying to change value in table. Doesn't work.
        }
    }
}
}

不幸的是,这不起作用。我甚至不知道修改curCell引用变量的值是否会实际改变table1Array在该位置的值,更不用说它是否会改变表中的数据。

我是否正确使用了indexOf属性?我应该使用!=比较运算符还是!==?indexOf是否以a的形式返回索引?是否有其他更简单、更优雅的方法?我刚开始使用jQuery,也许它可以帮助简化代码,使其更不容易出错。

抱歉所有的问题,我真的想了解这一切是如何工作的。谢谢!

您应该得到一个行数组,每行是一个单元格数组。这样验证就容易多了。我不确定你想怎么表现这种冲突。在这个演示中,我只是用红色突出显示了重复的单元格(冲突)(至少我喜欢这种显示冲突的方式,而不是修改冲突单元格的文本)。

:

<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);

演示。

请注意,我为所有单元格设置了contenteditable (td),您可以编辑单元格文本到您想要的内容并单击按钮来测试演示。

可以使用表行和单元格集合进行迭代。下面对文本内容进行了文字比较,您可能希望首先处理文本,以便在空白方面"规范化"它。

<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>

注意,一行中重复的文本将被报告两次。

上面使用了textContent属性,在某些用户代理中可能支持innerText。它的运行速度比jQuery快10倍。