【问题标题】:JS Find the missing letter (alphabet - array)JS 查找丢失的字母(字母 - 数组)
【发布时间】:2021-09-12 11:00:07
【问题描述】:

编写一个函数,该函数将一个连续(递增)字母数组作为输入,并返回数组中缺失的字母。 它总是会丢失一个字母。该数组将始终仅在一种情况下包含字母。 示例:

["a","b","c","d","f"] -> "e" ["O","Q","R","S"] -> "P"

为什么我的函数不起作用?

function findMissingLetter(array)
{
  let alphabetArr = Array.from('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
  let alphabetSlice = alphabetArr.slice(alphabetArr.indexOf(array[0]), alphabetArr.indexOf(array[array.length - 1]) + 1);

    let missingLetter = alphabetSlice.forEach((e, i) => {
         if (e !== array[i]) {
            return e;
        }
    });

return missingLetter;
}


function findMissingLetter(array)
{
  let alphabetArr = Array.from('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
  let alphabetSlice = alphabetArr.slice(alphabetArr.indexOf(array[0]), alphabetArr.indexOf(array[array.length - 1]) + 1);

    let missingLetter = alphabetSlice.map((e, i) => {
         if (e !== array[i]) {
            return e;
        }
    })[0];

return missingLetter;
}

【问题讨论】:

  • 不工作怎么办?你期待什么结果?你会得到什么?你做了什么调试?
  • forEachmap 都不是在数组中查找单个项目的正确方法。要么使用for/for-of 循环,你可以跳出(可能是for,因为你想要索引),或者find(找到项目本身),或者findIndex(找到它的索引) .你的基本方法很好。查看find 并阅读回调应该返回的内容,你会很好的。 :-)
  • findMissingLetter(["a","b","c","d","f"]) 我没有定义。
  • 但是 for/for-of 循​​环不是和 forEach 方法完全一样吗?
  • "...you can break out of..." 这句话的一部分很重要。 :-) 你不能跳出forEach(除非抛出错误)。

标签: javascript arrays alphabetical


【解决方案1】:

要在数组中搜索一个元素,请使用for 循环,如下所示:

for(let i = 0; i < array.length; i++) {
    if(array[i] !== alphabetSlice[i])
        return alphabetSlice[i];
}

在这种方法中,您将搜索两个数组之间的第一个差异。不同之处将是您丢失的字母:)


为什么地图在这个例子中不起作用?

map 函数获取数据并将其替换为“重新排列”的数据。这个:

alphabetSlice.map((e, i) => {
    if (e !== array[i]) {
        return e;
    }
}); // for your example will create array 

将创建[undefined, undefined, undefined, undefined, 'e', 'f'],所以第一个元素是undefined

为什么结果数组有undefined

因为您在if 中有return 语句。所以当if中的表达式为false时,你不会返回任何值,所以值为undefined

您可以在mdn阅读有关地图的更多信息。

【讨论】:

    【解决方案2】:

    实际上只需将forEach 替换为find 并更改您返回的内容,它就会执行所需的操作。

    function findMissingLetter(array)
    {
        let alphabetArr = Array.from('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
        let alphabetSlice = alphabetArr.slice(alphabetArr.indexOf(array[0]), alphabetArr.indexOf(array[array.length - 1]) + 1);
    
        let missingLetter = alphabetSlice.find((e, i) => { // ***
            return e !== array[i];                         // ***
        });
    
        return missingLetter;
    }
    
    console.log(findMissingLetter(["a","b","c","d","f"]))
    console.log(findMissingLetter(["O","Q","R","S"]))

    Array.prototype.forEach() 为每个数组元素执行一次提供的函数。

    Array.prototype.find() 返回提供的数组中满足提供的测试功能的第一个元素的值。

    【讨论】:

      【解决方案3】:

      在循环遍历每个元素之前,无法从forEach 循环返回。 而forEach 总是返回undefined

      您可以通过const missingLetter = alphabetSlice.find((e, i) =&gt; e !== array[i]);找到这封信

      【讨论】:

        【解决方案4】:
        1. 0length - 1 遍历数组
        2. 在每次迭代中,使用String#charCodeAt获取当前字符和下一个字符的UTF-16 code,如果它们彼此之后应该有1的差异(假设它们的大小写相同)
        3. 如果next 元素的代码不等于当前的1 + 1,则在当前代码上使用String#fromCharCode + 1 计算缺少的字符

        const findMissingLetter = (array = []) => {
          for(let i = 0; i < array.length - 1; i++) {
            const current = array[i].charCodeAt(), next = array[i+1].charCodeAt();
            const expected = current+1;
            if(next !== expected) {
              return String.fromCharCode(expected);
            }
          }
        }
        
        console.log( findMissingLetter(["a","b","c","d","f"]) );
        console.log( findMissingLetter(["O","Q","R","S"]) );

        【讨论】:

          【解决方案5】:

          已经描述的答案和 cmets,为什么它不起作用以及为什么你会得到意想不到的结果。我只是想展示一种不同的方法来解决这个问题。

          您可以利用这样一个事实,即 unicode 字符已经排序并将任何值的代码点加一,将为您提供以下字母/字符/数字。

          您所要做的就是从数组中的最低值和最高值获取代码点,并测试中间是否有任何字符在您正在测试的数组中。

          使用此方法,您可以在任何范围内进行测试,如果通过列表中缺少字母/字符/表情符号。

          function missingChars(arr) {
            if (Array.isArray(arr)) {
              // generate a sorted copy of the array passed as argument
              arr = arr.slice().sort();
              // length won't be 1 on emojis and so on, so just test for > 0
              if (!arr.every(val => (typeof val == 'string' || val instanceof String) && val.length)) {
                  throw new Error("Every value must be a string with length > 0.");
              }
              // lowest item will be at pos 0 after sort()
              const first = arr[0].codePointAt(0),
                // highest item will be at the last position
                last = arr[arr.length-1].codePointAt(0),
                resultArr = [];
              // for every char in between the lowest and the highest
              for (let i = first; i < last;i++) {
                // create a string using his code point value
                const charToTest = String.fromCodePoint(i);
                // test if it is inside the array
                if (!arr.includes(charToTest)) {
                  // if not, add it to  the result
                  resultArr.push(charToTest);
                }
              }
              return resultArr;
            }
            return null;
          }
          
          console.log(missingChars(["?", "?"])); // ['?', '?', '?', '?", '?', '?']
          console.log(missingChars(["e", "c", "a"])); // ['b', 'd']
          console.log(missingChars(["0", "2"])); // ['1']
          console.log(missingChars(["a", "b"])); // []
          
          // ascii range
          console.log(missingChars(['\u0000', '\u00FF'])); 
          
          console.log(missingChars(['', 'a'])); // throws error

          【讨论】:

            【解决方案6】:

            Array.forEach 不返回任何内容 - 就像其他人已经回答一样。 forEach 只是对数组的所有元素执行 (lambda) 函数。

            您可能想检查Array.find,其他人也注意到了这一点。

            这里有一个更通用的解决方案(检查 alfabet 或其他给定字符串中的缺失):

            const findFirstMissing = (arr, from) => [...from
              .slice(from.indexOf(arr[0]), from.indexOf(arr[arr.length - 1]) + 1) ]
              .find((v, i) => v !== arr[i]) || `complete`;
            
            let alfabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
            console.log(findFirstMissing(["a", "b", "c", "d", "f"], alfabet));
            console.log(findFirstMissing(["O", "Q", "R", "S"], alfabet));
            
            let someRowOfCharacters = `Charlotte`;
            console.log(findFirstMissing(`Charltte`.split(``), someRowOfCharacters));
            console.log(findFirstMissing(`Charlotte`.split(``), someRowOfCharacters));

            【讨论】:

              猜你喜欢
              • 2014-03-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-04-04
              • 2019-01-01
              • 1970-01-01
              • 2013-10-27
              • 1970-01-01
              相关资源
              最近更新 更多