【问题标题】:How can I compare strings as unordered elements of two arrays?如何将字符串作为两个数组的无序元素进行比较?
【发布时间】:2021-07-14 14:34:41
【问题描述】:

我还在学习 js,但我在理解这个练习中犯了什么错误时遇到了一些困难。该练习来自 FCC:如果数组第一个元素中的字符串包含数组第二个元素中字符串的所有字母,它会要求返回 true。

到目前为止,我已经尝试了几种方法,但我觉得最后一种方法是我能得到的最接近的方法。到目前为止,我已经想出了这个(请注意,在将代码插入 FCC 的功能之前我正在尝试代码):

    let array = ["floor", "for"];
    
    let lowercase = array.map(name => name.toLowerCase());
    let string1 = lowercase.slice(0, 1).toString();
    let string2 = lowercase.slice(1).toString();

    let arraysplit1 = string1.split("").sort();
    let arraysplit2 = string2.split("").sort();

    for (let i = 0; i < arraysplit2.length; i ++) {
    for (let j = 0; j < arraysplit1.length; j ++){
      if (arraysplit1.indexOf(arraysplit2[i]) != -1){
         console.log("ok");
        
        
        }
    else {
        console.log("not ok");
        
    }
    }

    }

如您所见,首先我将所有内容都转换为小写(以防两个值中的一个为大写)。然后切片并串成 2 个不同的数组(很可能有一种方法可以在不创建 2 个不同数组的情况下解决这个问题,但我觉得划分 2 个单词更舒服)。对各种字母进行拆分和排序(排序实际上没用,因为无论如何我都想检查每个人)。 现在真正的问题在于 2 个 for 循环和以下 if 语句:似乎我无法正确理解这些逻辑,因为它不起作用。

如果我做错了什么,我将不胜感激。非常感谢!

【问题讨论】:

标签: javascript arrays string indexof


【解决方案1】:

这里不需要两个循环。您只需要遍历第二个单词中的字符并检查每个字符是否存在于第一个单词中。

如果您遇到firstWord.indexOf(c) 为-1 的角色,则答案为否/假,否则为是/真。您可以使用Array.everyArray.includes 来稍微简化您的代码,但无论哪种方式都可以。

如果你把它变成一个函数,你可以让它为任何两个词返回真或假,这将阐明预期的行为并将其封装以方便使用:

function hasAllChars (wordA, wordB) {
  // ...
  return true;
}

console.log(hasAllChars("floor", "for")); // true

if (hasAllChars("floor", "for")) {
  // do stuff
}

单个for循环

这是一个使用单个 for 循环的实现:

function hasAllChars(wordA, wordB) {
  const charsB = wordB.split('');
  for (let i = 0; i < charsB.length; i++) {
    if (wordA.indexOf(charsB[i]) === -1) {
      return false;
    }
  }
  return true;
}

console.log(hasAllChars("floor", "for")); // true
console.log(hasAllChars("floor", "fort")); // false

使用 Array.every:

这是一个使用every 和indexOf 的更简单的实现:

function hasAllChars(wordA, wordB) {
  const charsB = wordB.split('');
  return charsB.every(char => wordA.indexOf(char) > -1);
}

console.log(hasAllChars("floor", "for")); // true
console.log(hasAllChars("floor", "fort")); // false

【讨论】:

  • 感谢您的回答,但练习要求仅当数组的第一个元素中的字符串包含第二个元素中字符串的所有字母时才返回 true。例如,当你有 ["floor", "for"] 时,应该返回 "true",因为单词 "for" 的每个字母都包含在单词 "floor" 中(但不是整个单词 "for",因为在第一个中间有一个“L”)。
  • 对。这就是这样做的。还是我错过了什么?
  • 单循环的例子是最有帮助的:毕竟它只需要循环。感谢您的帮助!
【解决方案2】:

我倾向于使用[...str] 而不是str.split('') 来分割字符串。原因如下:

[...'???']
//=> ["?", "?", "?"]

// vs

'???'.split('')
//=> ["\ud83c", "\udf2f", "\ud83c", "\udf2f", "\ud83c", "\udf2f"]

您只需要检查一封信。在'floor' 中,您只需检查一次'o'。所以你需要一套:

new Set([...'floor'])
//=> Set(4) {"f", "l", "o", "r"}

// vs

[...'floor']
//=> ["f", "l", "o", "o", "r"]

假设a 可以包含b 的所有字符,但不仅限于那些我们可以遍历b 的字符:

const check = (a, b) => {
  const as = new Set([...a]);
  const bs = new Set([...b]);
  for (let c of bs) if (!as.has(c)) return false;
  return true;
}

console.log(check("floor", "for"));
console.log(check("floor", "fot"));
console.log(check("???", "?"));
console.log(check("???", "??"));

【讨论】:

  • 感谢您的解释,但不幸的是对我来说太高级了。 .has 和 Sets 之类的东西我仍然遥不可及。
【解决方案3】:

如果你可以使用every():

let array = ["floor", "for"];
const res = array[1].split('').every(elem => array[1].split('').indexOf(elem) > -1);
console.log(res)

【讨论】:

  • 感谢您的回答。我几乎可以使用一切来解决它,但我认为如果我只使用真正基本的 js 方法(for 循环、if 语句等)会更好,因为这些都是我现在熟悉的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-02
  • 1970-01-01
  • 1970-01-01
  • 2013-02-08
相关资源
最近更新 更多