如何构建一个搜索字符串出现的函数?

How to build a function that searches for string occurrences?

我需要帮助编写一个函数 subLength(),它接受 2 个参数,一个字符串和一个字符。该函数应在字符串中搜索字符的两次出现以及 return 它们之间的长度,包括 2 个字符。如果字符出现少于 2 次或超过 2 次,函数应该 return 0。如何使用循环解决此问题?

        subLength('Saturday', 'a'); // returns 6
        subLength('summer', 'm'); // returns 2
        subLength('digitize', 'i'); // returns 0
        subLength('cheesecake', 'k'); // returns 0

你可以试试这个逻辑:

  • 遍历字符串并计算出现次数
  • 如果计数为 2,
    • 创建一个正则表达式来捕获中间的字符串。
    • Return它的长度
  • 否则return0

function subLength(str, char) {
  let length = 0;
  const occuranceCount = Array
    .from(str)
    .filter((c) => c.toLowerCase() === char.toLowerCase())
    .length
  if (occuranceCount === 2) {
    const regex = new RegExp(`${char}(.*)${char}`)
    length = str.match(regex)[0].length
  }
  console.log(length)
  return length;
}

subLength('Saturday', 'a'); // returns 6
subLength('summer', 'm'); // returns 2
subLength('digitize', 'i'); // returns 0
subLength('cheesecake', 'k'); // returns 0

仅使用 for 循环:

function subLength(str, char) {
  let count = 0;
  let initPosition;
  let lastPosition;
  for (let i = 0; i < str.length; i++) {
    if (str[i] === char) {
      count++
      if (count > 2) {
        return 0;
      }
      if (initPosition === undefined) {
        initPosition = i
      } else {
        lastPosition = i+1
      }
    }
  }
  return count < 2 ? 0 : lastPosition - initPosition;
}

console.log(subLength('Saturday', 'a')); // returns 6
console.log(subLength('summer', 'm')); // returns 2
console.log(subLength('digitize', 'i')); // returns 0
console.log(subLength('cheesecake', 'k')); // returns 0

在这里,我循环遍历字符串的字符以找到作为字符的每个值。

  • 如果长度不是 2,return0。
  • 使用切片,只获取找到的两个索引中的字符,并将该长度加一以固定偏移量

const subLength = (str, char) => {
    let strChars = str.toLowerCase().split(""),
        found = [],
        length = 0;
    
    strChars.forEach((val, index) => {
        if (val === char) {
            found.push(index);
        }
    });

    if (found.length != 2) {
        return length;
    }

   return str.slice(found[0], found[1]).length + 1;
}

console.log(subLength('Saturday', 'a')); // returns 6
console.log(subLength('summer', 'm')); // returns 2
console.log(subLength('digitize', 'i')); // returns 0
console.log(subLength('cheesecake', 'k')); // returns 0

我得到的答案是这样的:

const subLength = (str, char) => {
  let charCount = 0;
  let len = -1;
  
  for (let i=0; i<str.length; i++) {
    if (str[i] == char) {
      charCount++;
      if (charCount > 2) {
        return 0;
      }
      if (len == -1) {
        len = i;
      } else {
        len = i - len + 1
      }
    }
  }
  if (charCount < 2) {
    return 0;
  }

  return len;
};

我也在学习 Codecademy 课程,这个问题让我想到了这个 post。

使用@Rajesh 提供的 RegExp 解决方案(谢谢!!)我开始分解它以更好地理解正在发生的事情并做出 notes/comments 因为我还是很新而且还没有使用过或者接触过其中一些东西。

最后,我想我会分享我的结果,以防有人发现它有帮助。

function subLength(str, char) {
  // Outputting to the console what we are looking for given the value of the string and character from the test cases at the end of this script.
  console.log(`Showing the subLength for the string: "${str}" between "${char}" and "${char}" including the "${char}" positions.`);
  // create the length variable which will be returned by the function
  let length = 0;
  // ** Search the string for the two occurrences of the character and count them. Then assign the result to the occurrenceCount variable for use in the if else statement.

  // The "Array" class is a global object that is used in the construction off arrays.

  // The Array.from() static method creates a new, shallow-copied Array instance from an array-like or iterable object.

  // The Array.filter() method creates a new array with all elements that pass the test implemented by the provided function. The "c" represents each element of the array/string which is then compared to the char variable. if it is a match it gets added to the Array. We use .toLowerCase on both to ensure case compatibility.

  // Appending the Array with ".length" assigns occurrenceCount the numeric value of the array's length rather than the array of characters.

  const occurrenceCount = Array.from(str).filter((c) => c.toLowerCase() === char.toLowerCase());
  console.log(' The contents of the occurrenceCountArray = ' + occurrenceCount);
  console.log(' The character occurrence count = ' + occurrenceCount.length);
  // if the string has two occurrences : return the length between them including the two characters : else the string has less than 2 or more than 2 characters : return 0.
  if (occurrenceCount.length === 2) {
    // The RegExp object is used for matching text with a pattern. The "(.*)" in between the ${char}'s will match and capture as much as possible aka greedy match. "()" = capture anything matched. (" = start of group. "." = match any character. "*" = Greedy match that matches everything in place of the "*". ")" = end of group.
    const regex = new RegExp(`${char}(.*)${char}`);
    // log to console the pattern being matched
    console.log(`   regex pattern to find = ${regex}`);
    // log to the console the [0] = index 0 pattern that was captured from the string using str.match(regex)[0]
    console.log(`   regex output = ${str.match(regex)[0]}`);

    // Use".length" to count the number of characters in the regex string at index 0 of the regex array and assign that value to the length variable.
    length = str.match(regex)[0].length;

    // Output the results to the console
    console.log(`   The distance from "${char}" to "${char}" (including the "${char}" positions) in the string: ${str} = ${length}\n`);

    // return the length value
    return length;
  } else {
    // Output the results to the console
    console.log(`   The string either has too many or too few occurrences.\n    The subLength = ${length}\n`);
    // return the length value
    return length;
  }
}

// test cases
subLength('Saturday', 'a'); // returns 6
subLength('summer', 'm'); // returns 2
subLength('digitize', 'i'); // returns 0
subLength('cheesecake', 'k'); // returns 0