A function that collects an array of numbers as a parameter and returns an array of percentages?

I am currently starting out and trying to figure out how to basically use a function, get an array of numbers from each input, and then figure out how to make an individual percentage for each candidate. In JS, using this to get the total, but is there a way to get each individual number from each input in some way? Maybe I'll go in the wrong direction with a for: / loop. Any direction or hint would be great.

<div>
<label for="votes1">Votes for Candidate 1</label>
<input type="number" name="votesPerPerson" id="cand1" placeholder="Vote count">
</div>
<div>
<label for="votes2">Votes for Candidate 2</label>
<input type="number" name="votesPerPerson" id="cand2" placeholder="Vote count">
</div>
<div>
<label for="votes3">Votes for Candidate 3</label>
<input type="number" name="votesPerPerson" id="cand3" placeholder="Vote count">
</div>


<output id="totalvotes"></output>

      

Here's the JS for it

function totalVotes() {
  var votes = document.getElementsByName("votesPerPerson");
  var totalVotes = 0;
  for( var i = 0; i < votes.length; i ++ ) {
  totalVotes += parseInt(votes[i].value);
}
 document.getElementById("totalvotes").innerHTML = totalVotes;
}

      

+3


source to share


3 answers


It looks like you have a good understanding of how to get the amount. You can do several ways to create an array, but I recommend displaying it from a collection of items like this:



function totalVotes() {
  var votes = document.getElementsByName("votesPerPerson");
  var total = document.getElementById("totalvotes");
  // create new array
  var percentages = [];
  var totalVotes = 0;

  // reset innerHTML in case loop returns early due to invalid value
  total.innerHTML = "";
  
  // reset each vote percentage
  for (var i = 0; i < votes.length; i++) {
    votes[i].nextElementSibling.innerHTML = "";
  }

  // overwrite each index with value
  for (var i = 0; i < votes.length; i++) {
    totalVotes += percentages[i] = parseInt(votes[i].value);
    
    // one of the values is invalid
    if (isNaN(percentages[i])) return;
  }

  total.innerHTML = totalVotes;

  // calculate percentages here by mapping array of votes
  for (var i = 0; i < percentages.length; i++) {
    percentages[i] = 100 * percentages[i] / totalVotes;
    
    votes[i].nextElementSibling.innerHTML = percentages[i].toFixed(2) + "%";
  }
}

document.addEventListener('change', totalVotes)
      

<div>
  <label for="votes1">Votes for Candidate 1</label>
  <input type="number" name="votesPerPerson" id="cand1" placeholder="Vote count">
  <output></output>
</div>
<div>
  <label for="votes2">Votes for Candidate 2</label>
  <input type="number" name="votesPerPerson" id="cand2" placeholder="Vote count">
  <output></output>
</div>
<div>
  <label for="votes3">Votes for Candidate 3</label>
  <input type="number" name="votesPerPerson" id="cand3" placeholder="Vote count">
  <output></output>
</div>

<output id="totalvotes"></output>
      

Run codeHide result


+1


source


function totalVotes() {
  var votes = document.getElementsByName("votesPerPerson");
  var totalVotes = 0;
  var percentages = [];
  for( var i = 0; i < votes.length; i ++ ) {
    totalVotes += parseInt(votes[i].value);
    percentages[i] = parseInt(votes[i].value);
  }
  percentages = percentages.map(function(candidateVotes) {return candidateVotes/totalVotes;});
  document.getElementById("totalvotes").innerHTML = totalVotes;
}

      



The percentages are in an array with the same name, then you can do whatever you want! Hope this helps!

+1


source


You basically have an idea. You just need to attach some event handlers (with one other minor change).

function totalVotes() {
  var votes = document.getElementsByName("votesPerPerson");
  var totalVotes = 0;
  for(var i = 0; i < votes.length; i++) {
    totalVotes += parseInt(votes[i].value || 0); // "Minor change" here
  }
  document.getElementById("totalvotes").innerHTML = totalVotes;
}

// Additions below this point
var votes = document.getElementsByName("votesPerPerson");
for( var i = 0; i < votes.length; i ++ ) {
  votes[i].addEventListener('change', totalVotes);
}

totalVotes(); // Run once to get 0 to show without changing anything
      

<div>
  <label for="votes1">Votes for Candidate 1</label>
  <input type="number" name="votesPerPerson" id="cand1" placeholder="Vote count">
</div>
<div>
  <label for="votes2">Votes for Candidate 2</label>
  <input type="number" name="votesPerPerson" id="cand2" placeholder="Vote count">
</div>
<div>
  <label for="votes3">Votes for Candidate 3</label>
  <input type="number" name="votesPerPerson" id="cand3" placeholder="Vote count">
</div>


<output id="totalvotes"></output>
      

Run codeHide result


Now this code works, but notice some repetition, globals, etc. There is an alternative here that may offer you several different ways of solving the same things:

// If you want to know what this outer function is, look up "IIFE"
(function() {
  'use strict';

  // Get the elements (and make sure they are put in an array)
  var voteInputEls = Array.from(
    document.getElementsByName('votesPerPerson')
  );

  // This is used below to handle the change event
  function setTotalVotes() {

    // "reduce" the voteInputEls array to a total value
    var totalVotes = voteInputEls.reduce(function (lastVal, voteInputEl) {
      return lastVal + parseInt(voteInputEl.value || 0);
    }, 0);

    document.getElementById('totalvotes').innerHTML = totalVotes;
  }

  // Attach event listeners
  voteInputEls.forEach(function(voteInputEl) {
    voteInputEl.addEventListener('change', setTotalVotes);
  });
  setTotalVotes(); // Run once to get 0

})();
      

<div>
  <label for="votes1">Votes for Candidate 1</label>
  <input type="number" name="votesPerPerson" id="cand1" placeholder="Vote count">
</div>
<div>
  <label for="votes2">Votes for Candidate 2</label>
  <input type="number" name="votesPerPerson" id="cand2" placeholder="Vote count">
</div>
<div>
  <label for="votes3">Votes for Candidate 3</label>
  <input type="number" name="votesPerPerson" id="cand3" placeholder="Vote count">
</div>


<output id="totalvotes"></output>
      

Run codeHide result


0


source







All Articles