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 badges5 Answers
Reset to default 3For 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 addtoLowerCase()
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