如何将字符串作为两个数组的无序元素进行比较?

How can I compare strings as unordered elements of two arrays?

我仍在学习 js,我在理解我在这个练习中犯了什么错误时遇到了一些困难。该练习来自 FCC:如果数组第一个元素中的字符串包含数组第二个元素中字符串的所有字母,它会询问 return 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 语句中:似乎我无法理解那些正确的逻辑,因为它不起作用。

如果您对我做错的地方提出意见,我将不胜感激。非常感谢!

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

如果遇到firstWord.indexOf(c)为-1的字符,则答案为no/false,否则为yes/true。您可以使用 Array.every and Array.includes 稍微简化您的代码,但任何一种方法都有效。

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

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

我倾向于用 [...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("", ""));