finding the word at a position in javascript

前端 未结 6 2075
慢半拍i
慢半拍i 2020-12-10 06:18

For string input of \'this is a sentence\' it must return \'is\' when position is 6 or 7. When position is 0, 1, 2, 3 or 4 result must be \'this\'.

What is the easie

6条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-10 07:07

    I had some strange behavior in the most popular answer at time of writing with getting the word if the position is at the last character of a word that isn't the last word.

    Here's my rendition:

    • Instead of returning the word, I return the indices of the bounds of the word for more flexibility.
    • I use regular expressions for detecting whitespace, since the list of whitespace is quite large, varies under different locales, and is still relatively performant because only 1 character is checked.
    • Note: When the character at position and position-1 are at a space, the function returns [position, position]. This makes sense actually because the position does not have a word.
    function getWordBoundsAtPosition(str, position) {
      const isSpace = (c) => /\s/.exec(c);
      let start = position - 1;
      let end = position;
    
      while (start >= 0 && !isSpace(str[start])) {
        start -= 1;
      }
      start = Math.max(0, start + 1);
    
      while (end < str.length && !isSpace(str[end])) {
        end += 1;
      }
      end = Math.max(start, end);
    
      return [start, end];
    }
    

    To plug into substring, just deconstruct the returned bounds.

    const myString = 'This is a sentence.';
    const position = 7;
    
    const wordBoundsAtPosition = getWordBoundsAtPosition(myString, position);
    const wordAtPosition = myString.substring(...wordBoundsAtPosition); // => 'is'
    

    Cool Visualization

    I created a visualization of where the bounds returned by this method are in your string below:

    function getWordBoundsAtPosition(str, position) {
      const isSpace = (c) => /\s/.exec(c);
      let start = position - 1;
      let end = position;
    
      while (start >= 0 && !isSpace(str[start])) {
        start -= 1;
      }
      start = Math.max(0, start + 1);
    
      while (end < str.length && !isSpace(str[end])) {
        end += 1;
      }
      end = Math.max(start, end);
      
      return [start, end];
    }
    
    function analyzeStringWithCursor(str, bounds, cursorIdx) {
      document.getElementById("analysis").innerText = `
     ${"0123456789".repeat(Math.floor((str.length - 1) / 10) + 1)}
     ${str}
    ${" ".repeat(bounds[0])}↗${" ".repeat(bounds[1] - bounds[0])}↖
    Cursor: ${cursorIdx}
    getWordBoundsAtPosition("${str}", ${cursorIdx}): ${JSON.stringify(bounds)}
    substring(${bounds[0]}, ${bounds[1]}): "${str.substring(...bounds)}"
    `;
    }
    
    document.getElementById("input").onkeyup = e => {
      analyzeStringWithCursor(
        e.target.value,
        getWordBoundsAtPosition(e.target.value, e.target.selectionStart),
        e.target.selectionStart
      );
    };

    Type some words below. The cursor (moved by typing or arrow keys) indicates the current position.

提交回复
热议问题