I have some words like "Light Purple" and "Dark Red" which are stored as "LightPurple" and "DarkRed". How do I check for the uppercase letters in the word like "LightPurple" and put a space in between the words "Light" and "Purple" to form the word "Light Purple".
thanks in advance for the help
You can use a regex to add a space wherever there is a lowercase letter next to an uppercase one.
Something like this:
"LightPurple".replace(/([a-z])([A-Z])/, '$1 $2')
UPDATE: If you have more than 2 words, then you'll need to use the g flag, to match them all.
"LightPurpleCar".replace(/([a-z])([A-Z])/g, '$1 $2')
UPDATE 2: If are trying to split words like CSVFile, then you might need to use this regex instead:
"CSVFilesAreCool".replace(/([a-zA-Z])([A-Z])([a-z])/g, '$1 $2$3')
Okay, sharing my experience. I have this implement in some other languages too it works superb. For you I just created a javascript version with an example so you try this:
var camelCase = "LightPurple";
var tmp = camelCase[0];
for (i = 1; i < camelCase.length; i++)
{
var hasNextCap = false;
var hasPrevCap = false;
var charValue = camelCase.charCodeAt(i);
if (charValue > 64 && charValue < 91)
{
if (camelCase.length > i + 1)
{
var next_charValue = camelCase.charCodeAt(i + 1);
if (next_charValue > 64 && next_charValue < 91)
hasNextCap = true;
}
if (i - 1 > -1)
{
var prev_charValue = camelCase.charCodeAt(i - 1);
if (prev_charValue > 64 && prev_charValue < 91)
hasPrevCap = true;
}
if (i < camelCase.length-1 &&
(!(hasNextCap && hasPrevCap || hasPrevCap)
|| (hasPrevCap && !hasNextCap)))
tmp += " ";
}
tmp += camelCase[i];
}
Here is the demo.
You could compare each character to a string of uppercase letters.
function splitAtUpperCase(input){
var uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//start at 1 because 0 is always uppercase
for (var i=1; i<input.length; i++){
if (uppers.indexOf(input.charAt(i)) != -1){
//the uppercase letter is at i
return [input.substring(0,i),input.substring(i,input.length)];
}
}
}
The output is an array with the first and second words.
I think this is definitely not the best way to solve this problem (from an optimization perspective). But it works :)
const createSpacesBetweenWords = (char, index) => {
if (char === char.toUpperCase() && index > 0) {
return ` ${char}`;
}
return char;
};
function formatString(string) {
return string
.split('')
.map(createSpacesBetweenWords)
.join('');
}
formatString('LightPurple'); //returns a new string where words are separated by spaces
Related
There are two codes for the same problems the first work and the second doesn't work, even though they both get the same result, why the second isn't correct?
function generateHashtag(str) {
if (str.length >= 140 || str.length == 0) return false;
else {
let arr = str.split(" ");
for (let i = 0; i < arr.length; i++) {
if (arr[i] == "") arr.splice(i, 1);
}
for (let i = 0; i < arr.length; i++) {
arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].slice(1);
}
return "#" + arr.join("");
}
}
function generateHashtag(str) {
regex = /\b#/gi;
if (str.length >= 140 || str.length == 0) return false;
let res = str.replace(/\b\w/gim, (c) => c.toUpperCase());
let res2 = res.replace(/\s/g, "");
return "#" + res2;
}
this is the problem :
The marketing team is spending way too much time typing in hashtags.
Let's help them with our own Hashtag Generator!
Here's the deal:
It must start with a hashtag (#).
All words must have their first letter capitalized.
If the final result is longer than 140 chars it must return false.
If the input or the result is an empty string it must return false
The difference in implementation is that for the first function you split on a space, remove the empty entries and then replace the first char of the strings returned by the splitting.
But in the second function, you replace \b\w with an uppercase char. The issue is that the \b\w can match on more places than only at the start of a word.
You could write the second function asserting either the start of the string or match a whitespace character (?:^|\s)\w
You can also remove the /i flag as \w also matches lowercase chars (Or use [a-z] instead)
Note that you are not taking this rule into account, as you are checking this at the start of the function, but at the end you are removing spaces which can cause the total length of the string after the replacement being under 140.
If the input or the result is an empty string it must return false
For that you could check the length of the result instead.
function generateHashtag(str) {
if (str.trim() === "" || str.charAt(0) === "#") return false
const result = "#" + str
.replace(/(?:^|\s)\w/gm, c => c.toUpperCase())
.replace(/\s/g, "");
if (result === "" || result.length > 140) return false
return result;
}
const strings = [
"#CodeWars",
"this is a te$s#t",
"this is a te$s#t abcd abcd abcd abcd abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdab",
"this is a te$s#t abcd abcd abcd abcd abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdab dabcdabcdabcdabcdabcdabcdab",
"a",
"$",
"'#CodeWars'"
];
strings.forEach(s => console.log(generateHashtag(s)))
You can use
function generateHashtag (str) {
if (str === undefined || str.length === 0) return false;
str = (str.match(/\w+/g) || ['']).map(x => x.charAt(0).toUpperCase() + x.slice(1)).join("")
if (str.length == 0 || str.length > 139) { return false; }
else return "#" + str;
}
That is
if (str === undefined || str.length === 0) return false; returns false when the string is empty or undefined
str = (str.match(/\w+/g) || ['']).map(x => x.charAt(0).toUpperCase() + x.slice(1)).join("") extracts all words, capitalizes them, and joins into a single string
if (str.length == 0 || str.length > 139) { return false; } returns false if the result is empty or equals 140 or more
else return "#" + str; - returns the result as a hashtag with # prepended to the str.
function titleCase(str) {
let newStr = ''
for(let i = 0; i < str.length; i++){
if(str[i] == 0){
newStr += str[i].toUpperCase()//sets the first character of the String to uppercase
} else if (str[i - 1] == ' '){
newStr += str[i].toUpperCase();//sets every character that has a space before it to uppercase
} else {
newStr += str[i].toLowerCase();//sets any other character to lowercase
}
} return newStr
}
console.log(titleCase("I'm a liTTle tea pot")); // output: i'm A Little Tea Pot
if(str[i] == 0) should be if(i === 0) otherwise the check will be if the first character in the string is a zero
You need to check if the first index i.e i to be 0 or not, But you are checking equality for the character at 0 i.e I.
Since I is not equal to 0 so it skips the match.
So you need to change from
if(str[i] == 0){
to
if (i === 0) {
function titleCase(str) {
let newStr = "";
for (let i = 0; i < str.length; i++) {
if (i === 0) {
newStr += str[i].toUpperCase(); //sets the first character of the String to uppercase
} else if (str[i - 1] == " ") {
newStr += str[i].toUpperCase(); //sets every character that has a space before it to uppercase
} else {
newStr += str[i].toLowerCase(); //sets any other character to lowercase
}
}
return newStr;
}
console.log(titleCase("I'm a liTTle tea pot"));
This issue is with the if condition because currently is uses the value at index 0 not the index
The correct condition is
if(i==0)
For the first if condition you should change it to compare with i, not with str[i]. str[i] will not equal zero it is returning the first character of the string.
if(i == 0){newStr += str[i].toUpperCase();}
I need to pass an array of characters to a function, and extract from that array only letters and numbers; then I should pass those characters to a string and return the string. All of this using a function. I am getting an output warning that the function is not returning the correct value. Say the array was ['A','-','5','/','v','$,'f','4','%','2','3',''], the output should be ths string 'A5vf423'.
I am not sure if I need to declare arrayInput or str but I think the issue is that I am not passing correctly the characters from the vector to the string.
var high = function(arrayInput) {
var str = ' ';
for (var i = 0; i < arrayInput; i++) {
if (arrayInput[i] >= 'a' && arrayInput[i] <= 'a' &&
arrayInput[i] >= 'A' && arrayInput[i] <= 'Z'&&
arrayInput[i] >= '0' && arrayInput[i] <= '9') {
str = arrayInput[i].join('');
}
return str
};
}
EDIT: Solution:
return arrayName.filter(character => /^[a-zA-Z0-9]/.test(character)).join("")
You could use regex to match if is letter or number:
With filter checks each item and check if its letter or number and returns only items that is letter or number.
Regex:
[a-z|0-9] : includes any characters between a-z or 0-9
/i : non case sensitive
const arr = ["A", "/", "r", "6", ".", "a"];
function getString(arr) {
return arr.filter(l => l.match(/[a-z|0-9]/i)).join("")
}
console.log(getString(arr))
Reformat your conditional:
(arrayInput[i]>='a'&&arrayInput[i]<='z'||arrayInput[i]>='A'&&arrayInput[i]<='Z'||arrayInput[i]>='0'&&arrayInput[i]<='9')
Due to operator precedence, the above condition needs no brackets.
function high(arrayInput) {
let str = '';
for (let i = 0; i < arrayInput.length; i++) {
if ((arrayInput[i] >= 'a' && arrayInput[i] <= 'z') ||
(arrayInput[i] >= 'A' && arrayInput[i] <= 'Z') ||
(arrayInput[i] >= '0' && arrayInput[i] <= '9')) {
str += arrayInput[i];
}
}
return str;
}
I am trying to solve some JS problem. I want to check if an IP address is a valid one.
So the numbers must be between 0-255.
So what I want to do at this point, is to get an IP ex 192.168.1.1 and get substrings and load them to an array, so I want to create an array that looks like that:
array = ['192' , '168' , '1' , '1'];
I've tried various approaches in my algorithm but can't manage to target dynamically the numbers and split them between every dot.
I've done several tries, and thats the closest I could get.
let str = '192.168.1.1';
isValidIp(str);
function isValidIP(str) {
let array = [];
let substringArray = [];
for (let i=0; i<str.length; i++){
if (str[i] == '.') array.push(i);
}
let counter = 0;
for (let i in array){
substringArray.push(str.substring(counter, array[i]));
counter = array[i];
}
console.log(substringArray);
}
Which returns:
[ '192', '.168', '.1' ]
You can use the split() function of JavaScript which returns an array of every element separated by the digit specified. Or, which I wouldn't recommend, you could use RegEx. Here is an example of both:
function isValidIPwRegEx(str){
if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(str))
{
return true;
}
return false;
}
function isValidIP(str) {
let array = str.split("."),
isIP = true;
array = array.filter( block => !block.includes("+") && !block.includes("e") );
if(array.length!=4) return false;
array.forEach((number) => {
if ( !(+number >=0 && +number <= 255) ) { //As #p.s.w.g kindly suggested
isIP = false;
}
});
return isIP;
}
//With RegEx
console.log("With RegEx");
console.log(isValidIPwRegEx("192.168.1.1"));
console.log(isValidIPwRegEx("blah.blah.blah.blah")); //As #georg suggested
console.log(isValidIPwRegEx("1e1.2e1.+3e1.+5e1")); //As #georg again suggested to #Nina Scholz
console.log("");
//Without RegEx
console.log("Without RegEx");
console.log(isValidIP("192.168.1.1"));
console.log(isValidIP("blah.blah.blah.blah")); //As #georg suggested
console.log(isValidIP("1e1.2e1.+3e1.+5e1")); //As #georg again suggested to #Nina Scholz
console.log(isValidIP("1e1.2e1.3e1.5e1"));
Use String's split function.
So, something like "192.168.1.1".split(".")
You could split the string and check if the length is four and all values are integers and smaller than 256.
var ip = '192.168.1.1',
values = ip.split('.'),
valid = values.length === 4 && values.every(v => +v >= 0 && +v < 256);
console.log(values);
console.log(valid);
function isValidIP(str) {
let re = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
let m = str.match(re);
return m &&
m[1] >= 0 && m[1] <= 255 &&
m[2] >= 0 && m[2] <= 255 &&
m[3] >= 0 && m[3] <= 255 &&
m[4] >= 0 && m[4] <= 255
;
}
If you wish to be more precise, each digit check can be:
(0|[1-9]\d{0:2})
This prevents extraneous leading 0's.
I need to write a code with a function that has a parameter str that evaluates if the word is a palindrome or not, it should return true, else ir should return false.
Note: I need to remove all non-alphanumeric characters.
I wrote the code below but it is giving the opposite of the result expected:
It is giving false for all the cases.
Not able to remove the underscore.
and when use console.log below the image I get.
Code:
function palindrome(str) {
var exc = /[^\w_]/gi;
var repStr = str.toLowerCase().replace(exc, "");
console.log("Replaced string id: " + repStr);
len = repStr.length -1
for (var i = 0; i <= len; i++) {
if (str[i] !== repStr[len] - i) {
return false;
}
}
return true;
}
console.log(palindrome("eye"));
console.log(palindrome("_eye"));
console.log(palindrome("race car"));
console.log(palindrome("not a palindrome"));
console.log(palindrome("A man, a plan, a canal. Panama"));
console.log(palindrome("never odd or even"));
console.log(palindrome("nope"));
console.log(palindrome("almostomla"));
console.log(palindrome("My age is 0, 0 si ega ym"));
console.log(palindrome("1 eye for of 1 eye."));
console.log(palindrome("0_0 (: /-\ :) 0-0"));
console.log(palindrome("five|\_/|four"));
There are 2 mistakes in your code. 1) the RegExp is not replacing the underscore as [^\w_] reads as "everything that is not a word character OR an underscore". Try
/[\W_]/g
which reads as "one of the following: any character that is not a word character, underscores"
OR
/[^0-9a-z]/g
which reads as "anything that is not: digits (from 0 to 9), english alphabet letters".
2) For it to work you need to write
if(repStr[i] !== repStr[len - i])
instead of
if(str[i] !== repStr[len] - i)
you can simply replace the two of your lines
for (var i = 0; i <= len; i++, len--) {
if (str[i] !== repStr[len]) {
check this
function palindrome(str) {
var exc = /[^\w_]/gi;
var repStr = str.toLowerCase().replace(exc, "");
console.log("Replaced string id: " + repStr);
len = repStr.length -1
for (var i = 0; i <= len; i++, len--) {
if (str[i] !== repStr[len]) {
return false;
}
}
return true;
}
console.log(palindrome("eye"));
console.log(palindrome("_eye"));
console.log(palindrome("race car"));
console.log(palindrome("not a palindrome"));
console.log(palindrome("A man, a plan, a canal. Panama"));
console.log(palindrome("never odd or even"));
console.log(palindrome("nope"));
console.log(palindrome("almostomla"));
console.log(palindrome("My age is 0, 0 si ega ym"));
console.log(palindrome("1 eye for of 1 eye."));
console.log(palindrome("0_0 (: /-\ :) 0-0"));
console.log(palindrome("five|\_/|four"));
Try this out:
function palindrome(str) {
const letters = str.replace(/[^a-z]/gi, ''); // replace any char that is not in the set [a-z] range
const lowercase = letters.toLowerCase();
const reversed = lowercase.split('').reverse().join('');
return lowercase === reversed;
}