Выделить повторяющиеся значения строк JavaScript - PullRequest
0 голосов
/ 11 сентября 2018

Я использую JS для выделения дублирующихся значений в таблице.

В основном код выполняет добавление значения строк таблицы в массив, а затем сравнивает его, если оно существует, и затем выделяет эту строку.

Код работает нормально, но выделяет все повторяющиеся значения одним цветом (красным).Что мне нужно сделать, это выделить каждую группу одинаковых значений разным цветом.Допустим, у меня есть 4 группы повторяющихся значений, каждая группа должна быть выделена другим цветом.Возможно, цвета должны генерироваться случайным образом, поскольку в таблице может быть несколько повторяющихся значений.

 $(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', 'red');
            }
            $(this).css('backgroundColor', 'red');
            rowComposite.count++;
        }
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<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>
         <tr>
            <td class="content">C</td>
        </tr>
         <tr>
            <td class="content">C</td>
        </tr>
    </tbody>
</table>

Ответы [ 6 ]

0 голосов
/ 11 сентября 2018

Вы можете попробовать это. Просто и стильно:

$(function(){
    var st=document.createElement("style");
    document.head.appendChild(st);
    var sty={}, s;
    var A={}, cou=1;
    $("#sortable .content").each(function(i, c){
         if(!sty[c.innerHTML]){
            sty[c.innerHTML]=1;
            A[c.innerHTML]=cou++;
         }else sty[c.innerHTML]+=1;
         c.setAttribute("data-w", A[c.innerHTML]);
    });
    for(s in sty){
        if(sty[s]>1){
            st.sheet.insertRule("#sortable .content[data-w='"+A[s]+"']{background-color:rgb("+
                parseInt(Math.random()*256)+","+ 
                parseInt(Math.random()*256)+","+
                parseInt(Math.random()*256)+
            ");}", 0);
        };
    };
});

Извините, я набираю текст на своем мобильном телефоне, и у меня нет доступа к скрипке.


Попробуйте онлайн!

0 голосов
/ 11 сентября 2018

Вместо использования array для rowValues лучше использовать object, чтобы вы могли проверить наличие значения key.

Вы также можете использовать array цветов, откуда вы получаете динамические цвета, и постоянно сдвигать array, когда бы вы ни нашли новое значение, чтобы у каждого отдельного значения был свой соответствующий отдельный цвет.

И нет необходимости проверять count в блоке else, потому что всякий раз, когда вы достигаете этого блока, это означает, что этот value уже существует в array.

Вот как должен быть ваш код:

$(function() {
  var tableRows = $("#sortable tbody tr"); //find all the rows
  var colors = ["red", "blue", "green", "yellow", "#f5b"];
  var rowValues = {};
  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.color) {
        rowComposite.color = colors.shift();
      }
      rowComposite.count++;
      $(this).css('backgroundColor', rowComposite.color);
      $(rowComposite.row).css('backgroundColor', rowComposite.color);
    }
  });
});

Демо:

$(function() {
  var tableRows = $("#sortable tbody tr"); //find all the rows
  var colors = ["red", "blue", "green", "yellow", "#f5b"];
  var rowValues = {};
  tableRows.each(function() {
    var rowValue = $(this).find(".content").html();
    if (!rowValues[rowValue]) {
      var rowComposite = new Object();
      rowComposite.count = 1;
      rowComposite.row = this;
      rowComposite.color = colors.shift();
      rowValues[rowValue] = rowComposite;
    } else {
      var rowComposite = rowValues[rowValue];
      rowComposite.count++;
      $(this).css('backgroundColor', rowComposite.color);
      $(rowComposite.row).css('backgroundColor', rowComposite.color);
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<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>
    <tr>
      <td class="content">C</td>
    </tr>
    <tr>
      <td class="content">C</td>
    </tr>
  </tbody>
</table>
0 голосов
/ 11 сентября 2018
function random_rgba() {
    var o = Math.round, r = Math.random, s = 255;
    return 'rgba(' + o(r()*s) + ',' + o(r()*s) + ',' + o(r()*s) + ',' + r().toFixed(1) + ')';
}

$(function() {

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

здесь у вас это работает: https://jsfiddle.net/zn0g9u34/9/

0 голосов
/ 11 сентября 2018

Вы можете создать случайный цвет, используя пример пользовательской функции, как показано ниже

$(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',getRandomColor());
            }
           // $(this).css('backgroundColor', getRandomColor());
           $(this).css('backgroundColor', 'red');
            rowComposite.count++;
        }
    });
});

function getRandomColor() {
  var letters = '0123456789ABCDEF';
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<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>
         <tr>
            <td class="content">C</td>
        </tr>
         <tr>
            <td class="content">C</td>
        </tr>
        <tr>
            <td class="content">C</td>
        </tr>
    </tbody>
</table>
0 голосов
/ 11 сентября 2018

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

Для генерации случайного цвета я добавил метод, который имеет Set для отслеживания сгенерированных цветов. Он проверит, был ли сделан случайный цвет генератора, и продолжит генерировать цвета, пока не будет создан уникальный цвет.

Возможно, вы получите цвета, которые делают текст неразборчивым, или два случайных цвета, которые не имеют достаточного контраста, чтобы отличать их друг от друга. Так что это не идеальное решение.

function generateRandomInt(max, min = 0) {
  return Math.floor(Math.random() * (max - min + 1) + min);
}

/**
 * This method will return a new method, when the returned method is 
 * called it will return a unique color. Subsequent calls to the color
 * generator will never return the same color.
 */
function colorGenerator() {
  // Create a Set at the function scope which we can use to keep
  // track of the colors generated by the returned method.
  const
    generatedColors = new Set();
    
  return () => {
    let randomColor;
    // Keep generating a random color in the format "rgb(R,G,B)" until 
    // a color is generated that doesn't yet exist in the set. This doesn't
    // take into account that at some point you'll run out of 
    // possible colors (but it will take 16M+ tries).
    do {
      randomColor = `rgb(${generateRandomInt(255)},${generateRandomInt(255)},${generateRandomInt(255)})`;
    } while (generatedColors.has(randomColor));
    
    // Add the generated, unique, color to the set.
    generatedColors.add(randomColor);
    
    // Return the random color.
    return randomColor;  
  };
}

function highlightDoubles(table) {
  const
    // Get all the element with the content CSS class.
    contentCells = table.querySelectorAll('.content'),
    // Create map, the cell content will be the key and the value will be
    // an array with cells that have the key as content.
    contentMap = new Map();
   
  // IE doesn't support forEach on a NodeList, convert it to an array first.
  Array.from(contentCells).forEach(cell => {
    const
      // For each cell check if the content has been encountered before. If so
      // return the map value and else create a new array.
      array = (contentMap.has(cell.textContent))
        ? contentMap.get(cell.textContent)
        : [];
      // Push the current cell into the array.
      array.push(cell)
      // Store the array in the map.
      contentMap.set(cell.textContent, array);
  });

  // Create a color generator, it will create a random
  // color but never the same color twice.
  const 
    randomColor = colorGenerator();
    
  // Iterate over all the entries in the map, each entry is a unique 
  // cell content text
  contentMap.forEach(cells => {
    // When the lengths of the cells array is less than 2 it means 
    // it is not multiple times in the table. Exit now.
    if (cells.length < 2) {
      return;
    }
    
    // Generate a random color for the current content text. This is just
    // a very naive implementation. It doesn't make any promises on readability.
    const
      color = randomColor();
      
    // Apply the random color to all the cells with the same content.
    cells.forEach(cell => {
      cell.style.backgroundColor = color;
    });
  });
}

highlightDoubles(document.getElementById('sortable'));
<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>
         <tr>
            <td class="content">C</td>
        </tr>
         <tr>
            <td class="content">C</td>
        </tr>
    </tbody>
</table>
0 голосов
/ 11 сентября 2018

Всякий раз, когда вы создаете новый объект в операторе if, делайте что-то вроде

var rowComposite = new Object();
rowComposite.count = 1;
rowComposite.row = this;
var myColor = generateRandomColor();
rowComposite.color = myColor;

И затем, когда вы назначаете цвет, назначьте его .color вместо просто 'red':

$(rowComposite.row).css('backgroundColor', rowComposite.color);

Вы можете прочитать о генерации случайных цветов здесь: Генератор случайных цветов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...