最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to split a camelCase string and check if each split word is part of an array or not? - Stack Overflow

programmeradmin0浏览0评论

Assuming I have an array of words and a few camelCase strings as follows:

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

How would I split the camelCase words into individual strings, pare each split string (converted to lowercase) to the arr array elements and return true if every split string is part of the specified array?

"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

As suggested in this other SO thread, I tried to use the every() method and the indexOf() method to test if every split string can be found in the array or not as seen in the following Code Snippet but it's not working:

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"));

Assuming I have an array of words and a few camelCase strings as follows:

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

How would I split the camelCase words into individual strings, pare each split string (converted to lowercase) to the arr array elements and return true if every split string is part of the specified array?

"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

As suggested in this other SO thread, I tried to use the every() method and the indexOf() method to test if every split string can be found in the array or not as seen in the following Code Snippet but it's not working:

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"));

What am I doing wrong?

Share Improve this question edited Jan 29, 2019 at 11:41 AndrewL64 asked Jan 28, 2019 at 19:41 AndrewL64AndrewL64 16.3k8 gold badges50 silver badges85 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 3

For this particular case, I will use a lookahead assertion (?=...), which is a non-capturing construct and I will use it directly with the String::split() method. This will solve the problem of the extra generated empty string element on your array when the string begins with an uppercase letter. And also I will give a try to Array::includes() in exchange of indexOf()

const 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(
    "checkString(arr, 'HelloStackoverflow') =>",
    checkString(arr, "HelloStackoverflow")
);
console.log(
    "checkString(arr, 'itIsAwfullyColdDayToday') =>",
    checkString(arr, "itIsAwfullyColdDayToday")
);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

You have to convert your split strings to lowercase before doing the parison.

Also, you have to remove the empty string at the beginning of the list which is inserted by replace when the first letter of your string is uppercase.

You can use includes instead of 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"));

you were very close, but there was 2 problems:

  • one of them was on your str.replace, it was returning something like ["", "Hello", "Stackoverflow"] when you had a uppercase letter on the start of the string.

  • the second one was on your parison wordArray.indexOf() it is case sensitive, so you needed to add toLowerCase() so it ends up like this: 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"));

A few problems: first, all the arr values start with lowercase letters, but your camelCase tests (of course) contain caps. For that reason I've replaced

wordArray.indexOf(e)

with

wordArray.indexOf(e.toLowerCase())

Second, since your first test case starts with an uppercase letter, your regex is prepending a space, which then gets split into its own "word". To deal with this I've just added !e || to the every condition, so it will always return true for empty strings generated by leading caps.

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"));

This is a pretty simple version.

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'))

Of course you could also name the intermediate function:

const correct = checkString(arr)
correct('HaveAStackoverflowDay') //=> true

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论