【问题标题】:What is wrong with my function that accepts an array of 2 element and check if the first element has every letter in the second element?我的函数接受 2 个元素的数组并检查第一个元素是否包含第二个元素中的每个字母有什么问题?
【发布时间】:2017-02-04 00:58:28
【问题描述】:

给函数一个包含 2 个元素的数组,确切地说是 2 个字符串。如果第一个元素在第二个元素中包含每个字母(只有一次,没有大小写,没有顺序),则函数返回 true,如果不是 false。

嘿,你好。但是,例如, mutation(["zyxwvutsrqponmlkjihgfedcba", "qrstu"]) 不会以某种方式返回 true。我怀疑嵌套在 for 循环中的 if 语句有问题。我是多次返回 false 或 true,还是有其他问题?

function mutation(arr) {
  var one=arr[0];
  var two=arr[1];
  
  one.toLowerCase();
  two.toLowerCase();
  
  var array=two.split("");
  
  for(var i=0;i<array.length;i++){
    if(one.indexOf(array[i]) !== -1){
      return false;
    }else return true;
  }
  
  
}

mutation(["hello", "hey"]);

编辑: 新发现!如果我将 else return true 移动到 for 循环的结束括号之后,则 mutation("hello", "neo") 将根据需要返回 false。但是,如果我这样做了,那么 mutation("hello", "hey") 就不会返回 true,而在更改之前,它会。

【问题讨论】:

  • 你不能“多次返回”。一旦返回一个值,它就会被返回。该功能在此时完成执行。当您在调试器中单步执行此代码时,行为与您的预期有何不同?发生这种情况时变量的值是多少?
  • 大卫是对的,你已经在 for 循环中返回...

标签: javascript


【解决方案1】:

这个:

for(var i=0;i<array.length;i++){
  if(one.indexOf(array[i]) !== -1){
    return false;
  }else return true;
}

本质上(足够接近)与此相同:

if(one.indexOf(array[0]) !== -1){
  return false;
}else return true;

也就是说,你实际上并没有循环任何东西。因为,无论如何,您的循环总是在 first 迭代时返回。

考虑你的函数应该做什么的逻辑。如果我理解正确,如果循环遇到one 中未找到的字母,您想返回 false。如果循环 never 遇到这样的匹配,则返回 true。在这种情况下,默认条件 after 循环将返回 true。像这样的:

for(var i=0;i<array.length;i++){
  if(one.indexOf(array[i]) === -1){
    return false;
  }
}
return true;

基本上,如果循环从未找到“不匹配”,则它永远不会返回 false。所以返回 true。

编辑:我还更改了if 中的比较,因为我认为你把它颠倒了。但我想我不是 100% 确定这一点,因为该方法的意图有点不清楚。 (其中的逻辑有点混乱,而且方法的名称当然没有帮助。)但希望您至少能明白这一点,并可以根据您的需要进行相应的测试/验证。

【讨论】:

  • 是的,它是反向的。一个非常愚蠢的错误。我很不耐烦。感谢您指出这一点。
  • 我现在明白了。即解决问题。顺便说一句,应该是 one=one.toLowerCase();就是这样!
  • 很好的例子说明了循环的问题。但是,代码的逻辑无法满足问题中描述的条件。原始问题中提供的函数查找第二个字符串的所有字符是否都在第一个中,而不是相反。
【解决方案2】:

首先,如果您在one 中找到任何不在two 中的字符,您应该只返回false,但您只能在循环结束时返回true,因为这样您就知道所有字符都匹配。它不能在 else 块中。

第二,根据你的描述不应该是相反的吗?您应该迭代 one 的字符并查看它们是否在 two 中。那么它会适合。

function mutation(arr) {
  var one=arr[0].toLowerCase();
  var two=arr[1].toLowerCase();

  var oneArr=one.split("");
  var twoArr=two.split("");
  
  console.log("Do all of '" + one + "' characters occur in '" + two + "'?");

  for(var i=0;i<oneArr.length;i++){
    console.log("Looking for " + oneArr[i]);

    // If any characters in two didn't occur in one, it fails
    var twoIndex = twoArr.indexOf(oneArr[i]);
    if(twoIndex === -1) {
      console.log("Can't find " + oneArr[i]);
      return false;
    } else {
      console.log("Found at index " + twoIndex + " in '" + two + "'");
    }
  }
  return true;
}

console.log(mutation(["hey", "hello"]));

console.log(mutation(["qrstu", "zyxwvutsrqponmlkjihgfedcba"]));

【讨论】:

  • 所以改变是你删除了!并将 return true 移到循环之外。我说的对吗?
  • 是的,这是您的编程问题。在您的问题中,您说您需要第一个单词中的所有字符都出现在第二个单词中。但是在您的代码中,它会检查所有第二个字符是否都在第一个单词中。请参阅我的代码以了解该更改。
【解决方案3】:

主要问题是您使用 else 块在循环内返回 true,因此您的循环仅检查一个元素,然后根据该元素是否在第一个字符串中返回 true 或 false。将 return true 语句放在 for 循环之后。

第二个问题是,当您检查是否存在时,您将返回 false 如果它确实存在。请改用one.indexOf(array[i]) === -1

最后一个问题是您要拆分字符串以对其进行迭代,但字符串不需要拆分即可使用 for 循环进行迭代。

其余的更改只是使用更少的代码行来做同样的事情。

function mutation(arr) {
  arr = arr.map(e => e.toLowerCase());
  
  for(let i = arr[1].length - 1; i > -1; --i)
    if(arr[0].indexOf(arr[1][i]) === -1) return false;
  
  return true;
}

console.log(mutation(["hello", "hey"]));
console.log(mutation(["hello", "hel"]));
console.log(mutation(["zyxwvutsrqponmlkjihgfedcba", "qrstu"]));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 2019-05-10
    • 2021-01-30
    • 1970-01-01
    • 2022-11-16
    • 2014-06-05
    相关资源
    最近更新 更多