Search code examples
javascriptarraysjoinassociative-arraystring-concatenation

Javascript How To Concatenate Separate Characters Into One String In Array?


I wrote a code for a "Heads or Tails" game below and:

var userInput = prompt("Enter maximum number output: ");

function coinFlip() {
  return (Math.floor(Math.random() * 2) === 0) ? 'Heads' ; 'Tails';
}

for (var i = 0; i < 6; i++)
{
  var result = [];

  result["randomNum"] = (Math.floor(Math.random()*userInput);

  result["coin"] = (coinFlip());
}

I'm trying to count the sum of total heads and sum of total tails each with the code:

var headsCount = 0;
var tailsCount = 0;

for (var j = 0; j < result["coin"].length; j++)
{
   if (result["coin"] == 'Heads')
      headsCount++;
   else
      tailsCount++;
}

The only problem is that it's counting each characters of 'Heads' and 'Tails' in the result["coin"] array as separate (such as 'H'-'e'-'a'-'d'-'s') and not into a full string (like "Heads"). Thus, instead of increment by 1 each time the loop above runs, it increments by +5.

I want it to increment by +1 only.

How do I make it so that the code reads the full string stored in result["coin"] and not character-by-character?

EDITED -- changed the <2 to *2


Solution

  • var result = []; is inside the for loop, so it is being overwritten with an empty array each time. So when you try to loop over the results, there's one one item in it; the last one. Pull the result array out of the loop so that you can add to it in each iteration.

    It seems userInput should be the number of times to loop. Not sure why you're putting it in result["randomNum"]. result is an array, not an object, so it only has integer keys.

    Instead of adding the result of the coin toss to result["coin"] I think you mean to add it to the array, so after tossing it six times it might look like this: ["Heads", "Heads", "Tails", "Heads", "Tails", "Tails"]. You can do this by calling result.push with the coin toss output.

    To get one of two results randomly, compare the output of Math.random() against 0.5, which is half way between the limits. Numbers less than 0.5 can be considered heads, while numbers greater than or equal to 0.5 can be considered tails.

    Putting it all together, this is what I think you were going for:

    function coinFlip() {
      return Math.random() < 0.5 ? 'Heads' : 'Tails';
    }
    
    var result = [];
    var userInput = parseInt(prompt("Enter maximum number output: "), 10);
    for (var i = 0; i < userInput; i++) {
      result.push(coinFlip());
    }
    
    var headsCount = 0;
    var tailsCount = 0;
    
    for (var j = 0; j < result.length; j++) {
      if (result[j] == 'Heads')
        headsCount++;
      else
        tailsCount++;
    }
    
    console.log(headsCount, "heads and", tailsCount, "tails");

    All that being said, there are definitely areas for improvement. You don't need to loop once to build the results, then loop a second time to read the results.

    You can count the number of heads/tails as the coins are flipped. For example:

    function isCoinFlipHeads() {
      return Math.random() < 0.5;
    }
    
    var numFlips = parseInt(prompt("How many flips?"), 10);
    var heads = 0;
    var tails = 0;
    for (var i = 0; i < numFlips; i++) {
      isCoinFlipHeads() ? heads++ : tails++;
    }
    console.log(heads, "heads and", tails, "tails");