Home > Software engineering >  How to display only the highest "score" according to the text content inside each div?
How to display only the highest "score" according to the text content inside each div?

Time:08-24

I would like to archive the below by using JavaScript (or with jQuery). Here is the HTML structure:

<div >
  <div >A<div id="score">96 </div></div>
  <div >B<div id="score">99</div></div>
  <div >C<div id="score">99</div></div>
  <div >D<div id="score">96-</div></div>
</div>
<div >
  <div >A<div id="score">86</div></div>
  <div >B<div id="score">88</div></div>
  <div >C<div id="score">90</div></div>
  <div >D<div id="score">90 </div></div>
</div>
<div >
  <div >A<div id="score">83-</div></div>
  <div >B<div id="score">83 </div></div>
  <div >C<div id="score">76</div></div>
  <div >D<div id="score">78</div></div>
</div>

The JavaScript will do the modification, and the desired results will be B 99 C90 A 83- , which looks like:

<div >
  <div >B<div id="score">99</div></div>
</div>
<div >
  <div >C<div id="score">90</div></div>
</div>
<div >
  <div >A<div id="score">83-</div></div>
</div>

The rules are:

  1. Ignore all non-number in id="score", eg. and -, and do the ranking.
  2. Show one highest score item.
  3. If two score items are the same in a set, show just one according to the div item sequence inside <div >, ie. in the above example A > B > C > D.
  4. When writing the result, write the original div item, including or -.

CodePudding user response:

To be able to do this, it would be best to get each individual score-set and treat one after another.

For each score item, we need to first get the score and transform it (Array#map) into a number with no digits (.replace(\/D /g, ''))and memorize the score item html object.

Number(scoreItem.querySelector('div').innerText.replace(/\D /g, ''))

We can then sort the remaining ones in descending order and simply take the first one of the list. Can be done with Array#sort and destructuring assignment.

.sort(({ score: scoreA }, { score: scoreB }) => scoreB - scoreA)

Then finally we update the score set html.

scoreSet.innerHTML = '';
scoreSet.appendChild(scoreItem);

const scoreSets = document.getElementsByClassName('score-set');

for(const scoreSet of scoreSets){
  
  const [{ scoreItem }] = Array
    .from(scoreSet.getElementsByClassName('score-item'))
    .map(scoreItem => ({
      scoreItem,
      // it would be better here to access the score using the id
      // but `score` is used multiple times which makes getting 
      // the score element unreliable
      score: Number(scoreItem.querySelector('div').innerText.replace(/\D /g, ''))
    }))
    .sort(({ score: scoreA }, { score: scoreB }) => scoreB - scoreA)
    
  scoreSet.innerHTML = '';
  scoreSet.appendChild(scoreItem);
}
<div >
  <div >A
    <div id="score">96 </div>
  </div>
  <div >B
    <div id="score">99</div>
  </div>
  <div >C
    <div id="score">99</div>
  </div>
  <div >D
    <div id="score">96-</div>
  </div>
</div>
<div >
  <div >A
    <div id="score">86</div>
  </div>
  <div >B
    <div id="score">88</div>
  </div>
  <div >C
    <div id="score">90</div>
  </div>
  <div >D
    <div id="score">90 </div>
  </div>
</div>
<div >
  <div >A
    <div id="score">83-</div>
  </div>
  <div >B
    <div id="score">83 </div>
  </div>
  <div >C
    <div id="score">76</div>
  </div>
  <div >D
    <div id="score">78</div>
  </div>
</div>

CodePudding user response:

This can be MUCH simplified

Note I changed the invalid ID to

If you cannot do that, then change .querySelector(".score") to .querySelector("div")

document.querySelectorAll('.score-set').forEach(scoreSet => {
   const scores = [...scoreSet.querySelectorAll(".score-item")];
   scores.sort((a,b) => parseInt(b.querySelector(".score").textContent) - parseInt(a.querySelector(".score").textContent))
   scoreSet.innerHTML ="";
   scoreSet.append(scores[0])
})
<div >
  <div >A
    <div >96 </div>
  </div>
  <div >B
    <div >99</div>
  </div>
  <div >C
    <div >99</div>
  </div>
  <div >D
    <div >96-</div>
  </div>
</div>
<div >
  <div >A
    <div >86</div>
  </div>
  <div >B
    <div >88</div>
  </div>
  <div >C
    <div >90</div>
  </div>
  <div >D
    <div >90 </div>
  </div>
</div>
<div >
  <div >A
    <div >83-</div>
  </div>
  <div >B
    <div >83 </div>
  </div>
  <div >C
    <div >76</div>
  </div>
  <div >D
    <div >78</div>
  </div>
</div>

  • Related