0

I've found a large number of posts discussing find/replace methods for strings in arrays, however they all seem to rely on a 'static string' input for the replacement

ie:

var str = "Mr Blue has a blue house and a blue car";
var res = str.replace(/blue/g, "red");

I need to find and replace checking against an input event

var whichKey = (String.fromCharCode(event.keyCode));

but also dynamically find and replace the characters that match in a different string.

so to be clear:

I am making a game of 'hangman'

user presses 'W' (for instance) as a 'guess':

secretPuzzleSolution = ['s', 'o', 'l', 'u', 't', 'i', 'o', 'n']
puzzleUserSees = ['_', '_', '_', '_', '_', '_', '_', '_']

W is not in the puzzle so they will lose a 'try' if they press 'S' the code would check secretPuzzleSolution[] for 's' and replace all the '_' in puzzleUserSees[] to 's' at the correct places and returns a new puzzleUserSees = ['S', ' _ ', ' _ ', ' _ ', ' _ ', ' _ ', ' _ ', ' _ ',] as a result.

The code successfully finds the keypress in secretPuzzleSolution[] but I cannot so far get it to

  1. copy the position from secretPuzzleSolution[] so that the puzzleUserSees[] element is changed at the correct position

  2. replace ALL instances of the keypress, not just the first one (if there's two elements of 's' in secretPuzzleSolution[], change both at the correct positions in puzzleUserSees[]

what I've got so far, it does partially do the job, but as you can see is clearly broken in a number of ways. Any ideas?

Here's the section I'm working with:

document.onkeydown = function(e) {
  var whichKey = (String.fromCharCode(event.keyCode));
  var keyPress = whichKey.toLocaleLowerCase();
  var found = secretPuzzleSolution.find(function(element) {
    var isMatch = secretPuzzleSolution.indexOf(element);
    if (typeof(element) !== 'undefined') {
      puzzleUserSees.splice((isMatch), (isMatch), element);
      remainingMystery--;
    } else {
      guessList.push(keyPress);
      triesLeft--;
    }
    return element === keyPress;
  });

  if (remainingMystery <= 0) {
    document.getElementById('game-display-area').innerHTML = ('YOU WIN!')
  };
  console.log('These guesses were correct: ' + found);
};

The last thing I'll add is that I'm in school so I'm sure there's a fancy way to do this or with jQuery but there should be a simple way with just JS as that's all I'm supposed to know so far :)

something else I tried:

      var test_array = (secretPuzzleSolution.indexOf(keyPress) > -1);
      if (test_array === true) {
      console.log(keyPress + ' was found in the puzzle');
      for (i = 0; i < puzzleUserSees.length; i++) {
      if (keyPress === puzzleUserSees[i]) {
      puzzleUserSees.splice([i], keyPress)
      }
      }
      } else {
      triesLeft--;
      guessList.push(keyPress);
      console.log(keyPress + ' was NOT found');
      }

Thanks!

Saryn Summer
  • 103
  • 4
  • I don't really understand the question, but nothing require the argument to `replace` to be a literal. `str.replace('/blue/g', whichKey)` is fine. – Barmar Oct 10 '18 at 17:46
  • 1
    `splice(isMatch, isMatch, element)` is probably wrong. The second argument is the number of elements to remove and replace with the new elements, so it should probably be `1`. – Barmar Oct 10 '18 at 17:49
  • But if you just want to replace one element, you can just do `puzzleDisplay[isMatch] = element;`. – Barmar Oct 10 '18 at 17:50
  • clarified my question a bit I hope? – Saryn Summer Oct 10 '18 at 18:01
  • so as I hopefully clarified, i need something that works like: str.replace('/dynamic_variable/g', dynamic_variable) and somewhere else str.replace('/dynamic_variable/g', 'normal_static_string') not just str.replace('/blue/g', dynamic_variable) – Saryn Summer Oct 10 '18 at 18:06
  • `var isMatch = secretPuzzleSolution.indexOf(element);` won't work well if the element can appear multiple times in the solution. It will only return the position of the first match. – Barmar Oct 10 '18 at 18:08
  • Why would `element` ever be undefined? There are no undefined elements in `secretPuzzleSolution`. – Barmar Oct 10 '18 at 18:09
  • Shouldn't you be doing something like `isMatch = secretPuzzleSolution.indexOf(keyPress)` and then testing if this is not `-1`? – Barmar Oct 10 '18 at 18:10
  • This still has nothing to do with string replacing, since you're using an array, not a string. – Barmar Oct 10 '18 at 18:13
  • Would you be able to show me where that would go with the posted code snipped as an example? I understand the code you posted but I'm getting turned around on where it should go and what it should replace. – Saryn Summer Oct 10 '18 at 18:13
  • Welcome to Stack Overflow. It will be appreciated if you will post a full working code or an example of it – vrintle Oct 10 '18 at 18:15
  • As per my understanding, simple solution for this problem will be traverse secretPuzzelSolution and store index of each element that matches entered character then traverse each newly created array and replace puzzleUserSees element on that position with entered character – Abhay Sehgal Oct 10 '18 at 18:23

1 Answers1

1

You're making a classic mistake, looping through an array to search for something, and treating it as a failure for each non-matching element. See Searching array reports "not found" even though it's found

You shouldn't be using .find(), since it just returns the position of the first match. You need to use .each() to loop over the entire array. This receives the array index of the element, so you don't need to use .indexOf() which only returns the first position, and isn't useful when there can be multiple matches for a letter.

document.onkeydown = function(e) {
  var whichKey = (String.fromCharCode(event.keyCode));
  var keyPress = whichKey.toLocaleLowerCase();
  var found = false;
  secretPuzzleSolution.forEach(function(element, index) {
    if (element == keyPress) {
      found = true;
      puzzleUserSees = keyPress;
      remainingMystery--;
    }
  });
  if (!found) {
    triesLeft--;
  }
  if (remainingMystery <= 0) {
    document.getElementById('game-display-area').innerHTML = ('YOU WIN!')
  };
};
vrintle
  • 5,501
  • 2
  • 16
  • 46
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Great I will sniff a bit more in the each() direction. Thanks! – Saryn Summer Oct 10 '18 at 18:27
  • It worked! As usual, there was something else elsewhere in my code (that I didn't post) that was ALSO creating problems and your solution fixed my issues AND helped me find the error elsewhere. You made me very happy thank you a lot. :) – Saryn Summer Oct 10 '18 at 18:59