Как разделить строку camelCase и проверить, является ли каждое слово разделения частью массива или нет? - PullRequest
0 голосов
/ 28 января 2019

Предполагая, что у меня есть массив слов и несколько строк camelCase следующим образом:

var arr = ["hello", "have", "a", "good", "day", "stackoverflow"];
var str1 = "whenTheDayAndNightCollides";
var str2 = "HaveAGoodDay";
var str3 = "itIsAwfullyColdDayToday";
var str4 = "HelloStackoverflow";

Как бы я разбил слова camelCase на отдельныестрок, сравнить каждую строку разбиения (преобразованную в нижний регистр) с элементами массива arr и вернуть true, если каждая строка разбиения является частью указанного массива?

"whenTheDayAndNightCollides" // should return false since only the word "day" is in the array

"HaveAGoodDay" // should return true since all the words "Have", "A", "Good", "Day" are in the array

"itIsAwfullyColdDayToday" // should return false since only the word "day" is in the array

"HelloStackoverflow" // should return true since both words "Hello" and "Stackoverflow" are in the array

Как предлагается в этомдругой SO thread , я пытался использовать метод every () и метод indexOf () , чтобы проверить, можно ли найти каждую строку разбиения в массиве илине так, как показано в следующем фрагменте кода , но он не работает:

var arr = ["hello", "have", "a", "good", "day", "stackoverflow"];

function checkString(wordArray, str)
{
    // split the camelCase words
    var x = str.replace(/([A-Z])/g, ' $1').split(" ");

    return x.every(e => {
        return wordArray.indexOf(e.toLowerCase()) >= 0;
    });
}

console.log("should return true ->" + checkString(arr, "HelloStackoverflow"));
console.log("should return false ->" + checkString(arr, "itIsAwfullyColdDayToday"));

Что я делаю не так?

Ответы [ 5 ]

0 голосов
/ 28 января 2019

В этом конкретном случае я буду использовать прогнозное утверждение (?=...), которое является не захватывающей конструкцией, и я буду использовать его непосредственно с String :: split () метод.Это решит проблему дополнительного сгенерированного элемента empty string в вашем массиве, когда строка начинается с заглавной буквы.А также я дам попытку Array :: includes () в обмен на indexOf ()

var arr = ["hello", "have", "a", "good", "day", "stackoverflow"];

function checkString(wordArray, str)
{
    return str.split(/(?=[A-Z])/g).every(
        e => wordArray.includes(e.toLowerCase())
    );
}

console.log("should return true ->" + checkString(arr, "HelloStackoverflow"));
console.log("should return false ->" + checkString(arr, "itIsAwfullyColdDayToday"));
0 голосов
/ 28 января 2019

Это довольно простая версия.

const checkString = arr => str => str
  .split(/(?=[^a-z])/)
  .every(s => arr.includes(s.toLowerCase()))

const arr = ["hello", "have", "a", "good", "day", "stackoverflow"]

console.log(checkString(arr)('whenTheDayAndNightCollides'))
console.log(checkString(arr)('HaveAGoodDay'))
console.log(checkString(arr)('itIsAwfullyColdDayToday'))
console.log(checkString(arr)('HelloStackoverflow'))

Конечно, вы также можете назвать промежуточную функцию:

const correct = checkString(arr)
correct('HaveAStackoverflowDay') //=> true
0 голосов
/ 28 января 2019

вы были очень близки, но было 2 проблемы:

  • одна из них была на вашем str.replace, она возвращала что-то вроде ["", "Hello", "Stackoverflow"], когда у вас была заглавная буквав начале строки.

  • второй был по вашему сравнению wordArray.indexOf() он чувствителен к регистру, поэтому вам нужно было добавить toLowerCase(), чтобы получилось так: wordArray.indexOf(e.toLowerCase())

var arr = ["hello", "have", "a", "good", "day", "stackoverflow"];

function checkString(wordArray, str) {
  var x = str.replace(/([A-Z])/g, ' $1').split(" "); // split the camelCase words
  //filter spaces
  var filtered = x.filter(s => s != '');
  return filtered.every(e => {
    return wordArray.indexOf(e.toLowerCase()) >= 0;
  });
}

console.log("should return true ->" + checkString(arr, "HelloStackoverflow"));
console.log("should return false ->" + checkString(arr, "itIsAwfullyColdDayToday"));
0 голосов
/ 28 января 2019

Несколько проблем: во-первых, все значения arr начинаются со строчных букв, но ваши тесты camelCase (конечно) содержат заглавные буквы.По этой причине я заменил

wordArray.indexOf(e)

на

wordArray.indexOf(e.toLowerCase())

Во-вторых, так как ваш первый тестовый случай начинается с заглавной буквы, ваше регулярное выражение добавляет пробел, который затем получает split в свое собственное «слово».Чтобы справиться с этим, я просто добавил !e || к условию every, поэтому он всегда будет возвращать true для пустых строк, генерируемых начальными заглавными буквами.

var arr = ["hello", "have", "a", "good", "day", "stackoverflow"];

function checkString(wordArray, str) {
    var x = str.replace(/([A-Z])/g, ' $1').split(" "); // split the camelCase words
    return x.every(function (e) { return !e || wordArray.indexOf(e.toLowerCase()) >= 0; });
}

console.log("should return true ->" + checkString(arr, "HelloStackoverflow"));
console.log("should return false ->" + checkString(arr, "itIsAwfullyColdDayToday"));
0 голосов
/ 28 января 2019

Перед выполнением сравнения необходимо преобразовать разделенные строки в нижний регистр.

Кроме того, необходимо удалить пустую строку в начале списка, которая вставляется replace, когда первая букваваша строка в верхнем регистре.

Вы можете использовать includes вместо indexOf.

var arr = ["hello", "have", "a", "good", "day", "stackoverflow"];

function checkString(wordArray, str) {
    return str.replace(/([A-Z])/g, ' $1')
      .split(" ") // split on spaces
      .map(s => s.toLowerCase())
      .filter(s => s)
      .every(e => wordArray.includes(e));
}

console.log("should return true -> " + checkString(arr, "HelloStackoverflow"));
console.log("should return false -> " + checkString(arr, "itIsAwfullyColdDayToday"));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...