How can I find at least 1 uppercase in a string? - javascript

In es6 js I have :
good = word => {
word.split('').includes(w => w === w.toUpperCase())
}
console.log(good('Bla'))
How can I return true when finding 1 Uppercase in my string?

You can test the string using a regular expression with a character set of all uppercase letters [A-Z]:
const good = word => /[A-Z]/.test(word);
console.log(good('Bla'));
console.log(good('bla'));

Although there are much simpler ways to do this (the regex in Tushar's comment being one of them), it's possible to fix your attempt to work correctly by:
Removing the braces so that the function actually returns a value.
Using .some(), which takes a function as its argument. .includes() doesn't.
Addding const so you're actually declaring your function.
const good = word => word.split('').some(w => w === w.toUpperCase())
console.log(good('Bla'))
console.log(good('bla'))

You can do this if you want the index of it too.
function findUpperCase(str) {
return str.search(/[A-Z]/);
}

// The string which will go thorough the test
let theString = 'Hello World'
// Function to find out the answer
function stringCheck (receivedString) {
// Removing special character, number, spaces from the string to perform exact output
let stringToTest = receivedString.replace(/[^A-Z]+/ig, "")
// Variable to count: how many uppercase characters are there in that string
let j = 0
// Loop thorough each character of the string to find out if there is any uppercase available
for (i = 0; i < stringToTest.length; i++) {
// Uppercase character check
if (stringToTest.charAt(i) === stringToTest.charAt(i).toUpperCase()) {
console.log('Uppercase found: ' + stringToTest.charAt(i))
j++
}
}
console.log('Number of uppercase character: ' + j)
// Returning the output
if (j >= 1) {
return true
} else {
return false
}
}
// Calling the function
let response = stringCheck(theString)
console.log('The response: ' + response)

Related

Add spaces before Capital Letters then turn them to lowercase string

I'm trying to make a function that caps space in which it takes input like "iLikeSwimming" then it outputs "i like swimming".
This is my try:
function isUpper(str) {
return !/[a-z]/.test(str) && /[A-Z]/.test(str);
}
function capSpace(txt) {
var arr = Array.from(txt);
for (let i = 1; i < txt.length; i++){
if (isUpper(txt[i]) == true) {
arr.splice((i),0,' ')
}
}
return arr.join('').toString().toLowerCase();
}
It's good for strings with only one capital letter, however, it gets kind of weird with more than one.
Example Input and outputs:
Inputs:
capSpace("iLikeSwimming"); capSpace("helloWorld");
Outputs:
'i lik eswimming' 'hello world'
I'd really appreciate it if someone can point the issue with my code. I know there are other questions "similar" to this, but I'm trying to learn my mistake rather than just copying, I couldn't make sense of any of the other questions. Thank you!
The reason why it gets weird with strings that have more than 1 capital letter is that every time you find one, you add a blank space which makes the following indices increase in a single unit.
It's a simple workaround: just place a counter splitCount to keep track of how many spaces you've added and sum it with the index i to correct the indices.
function isUpper(str) {
return !/[a-z]/.test(str) && /[A-Z]/.test(str);
}
function capSpace(txt) {
var arr = Array.from(txt);
var splitCount = 0; // added a counter
for (let i = 1; i < txt.length; i++){
if (isUpper(txt[i]) === true) {
// sum it with i
arr.splice((i + splitCount),0,' ')
splitCount++; // increase every time you split
}
}
return arr.join('').toString().toLowerCase();
}
console.log(capSpace('iLikeSwimming'))
1) You can simply achieve this using regex and string replace method
const capSpace = (str) => str.replace(/([A-Z])/g, (match) => ` ${match.toLowerCase()}`);
console.log(capSpace("iLikeSwimming"));
console.log(capSpace("helloWorld"));
2) You can also do with split, map and join
const capSpace = (str) =>
str
.split("")
.map((s) => (/[A-Z]/.test(s) ? ` ${s.toLowerCase()}` : s))
.join("");
console.log(capSpace("iLikeSwimming"));
console.log(capSpace("helloWorld"));
Here's a simple one I made. Matches capital letters then replaces them.
const testString = "ILoveMoney";
function caps2Spaces(str) {
const matches = str.match(/[A-Z]/g);
for (const letter of matches) {
str = str.replace(letter, ` ${letter.toLowerCase()}`)
}
return str.trim();
}
console.log(caps2Spaces(testString));

Counting brackets in a string

been working on a school problem, and haven't been able to figure it out. Any help is appreciated!
Write a function named countBrackets that accepts a string
and returns the count of square bracket and curly bracket
characters in the string. That is, it should count occurrences of
these four characters “{ } [ ]”. Use function expression syntax.
var countBrackets = function(s){
let sum = 0
for(let i = ""; i == s ; i++ )
if(i ==="{}[]"){
sum+=i
}
return sum}
console.log(countBrackets("[123],{456},[{}]")) //8
console.log(countBrackets("Test string")) // 0
I'm a little confused on how I'm supposed to get it to count a string I guess.
You can use a global regex (regular expression) matching for this. The regex is between / / followed by the g flag to make it global (otherwise it only returns the first result it finds and stops).
Within the regex, | is the OR operator, so you match for /{|}|[|]/
Since [ and ] have special meaning in regular expressions you need to escape those using a \ so your total regex becomes /{|}|\[|\]/g.
This returns an array of matches, I called the function findBrackets.
To get the number of brackets, the function countBrackets just returns the .length of that array.
const findBrackets = str => str.match(/{|}|\[|\]/g);
const countBrackets = str => findBrackets(str) ? findBrackets(str).length : 0;
console.log(findBrackets('qw[e}rt[y]ui{}o{p'));
console.log(countBrackets('qw[e}rt[y]ui{}o{p'));
console.log(countBrackets('no brackets here'));
Edit: seeing the code you posted, you decided to use a for-loop to loop over your string, which is a totally valid solution.
Note that in my above example
const findBrackets = str => str.match(/{|}|\[|\]/g);
Is basically the same but a newer way of writing functions (with a few nuances)
I could have written:
var findBrackets = function(str) {
return str.match(/{|}|\[|\]/g);
}
instead which would be almost the same.
If you want to loop over a string, you can access a letter in the string by using square bracket notation, so for example
const testString = 'hello';
console.log(testString[1]);
Would output the letter 'e'.
So to use this in a function:
const countBrackets = (str) => {
let counter = 0;
for (let i = 0; i < str.length; i++) {
if (str[i] === '[' || str[i] === ']' || str[i] === '{' || str[i] === '}') {
counter++;
}
}
return counter;
}
console.log(countBrackets('qw[e}rt[y]ui{}o{p'));
Here you loop over the string from 0 to < length of the string and check every letter of it, by seeing if str[i] is {, }, [ or ], and if it is you increment a counter. After that's done you return the final count.

Why non-space elements in string aren't changing to upperCase

I want to write a function to change the characters in a string at even indices to uppercase. I don't want my program to count the spaces as an even index, even if it falls on an even index.
For example: 'This is a test' => 'ThIs Is A TeSt'
I originally had this solution, but I could not get it to work to ignore the space characters when counting the even indices.
function toWeirdCase(string) {
return string.split("").map((x,i) => i%2=== 0 && x!== " " ? x.toUpperCase() : x).join("")
}
This is my second attempt and I don't know why the string elements aren't actually changing to uppercase. Any help on this would be appreciated. It is just returning the original string.
function toWeirdCase(string) {
let indexCount = 0;
let isSpace = false;
for (let i = 0; i < string.length; i++) {
if (string[i] === " ") {
isSpace = true;
}
if (indexCount % 2 === 0 && !isSpace) {
string[indexCount] = string[indexCount].toUpperCase();
}
indexCount++;
isSpace = false;
}
return string;
}
Answer:
You can use a modified reduce function that utilizes a closure as a character counter. This has the benefit of completing the transformation in one pass:
["", ...str].reduce((n =>
(r, c) => r += /\s/.test(c) ? c : c[`to${n++ & 1 ? "Lower" : "Upper"}Case`]())(0)
);
Example:
const biUpperCase = str => ["", ...str].reduce((n =>
(r, c) =>r += /\s/.test(c) ? c : c[`to${n++ & 1 ? "Lower" : "Upper"}Case`]())(0)
);
let test = biUpperCase("This is a Test");
console.log(test);
Explanation:
n is a character counter that keeps track of all non-space characters. You can think of this as an additional index that only worries about non-space characters.
We use this to determine whether or not a character is an even or odd non-space character by performing bitwise AND ( n & 1 ) or, alternatively, by performing a modulus operation ( n % 2 )
r is the accumulator in the Array.prototype.reduce method. This is what is returned by our reduce method.
Since there was no secondary parameter to Array.prototype.reduce, the first index of the Array is used as the accumulator.
This is why we perform ["", ...str] instead of simply [...str].
Syntactically we could also have written [...str].reduce( fn , "" ) instead of ["", ...str].reduce( fn ), but this would alter our succinct code.
c is the current character that we are looking at within the string array. We use RegExp.prototype.match to determine if it's a space character.
if it is we simply add the space to r ( our accumulated string )
if it is not we add a transformed character to r ( our accumulated string )
To determine which case transformation( upper or lower ) should be applied we check if n ( our character counter ) is even or odd.
if n++ & 1 is truthy the case is lower
if n++ & 1 is falsy the case is upper
Aside:
You'll notice in the snippet and code I provided that I changed your parameter name string to str. The reason for this is because String is a built-in Constructor in JavaScript and it's best to never purposefully "cross the streams" when naming variables.
In the current way that you're attempting to use this variable it makes no difference since it's properly scoped, and truthfully it is up to you if you want to take my advice. Just be aware that it could lead to an annoying, invisible problem.
Hope this Helps! Happy Coding!
You could rewind the index counter for a single word.
function toWeirdCase(string) {
return Array
.from(
string,
(i => x => (/[a-z]/i.test(x) ? i++ : (i = 0)) % 2 ? x : x.toUpperCase())
(0)
)
.join('');
}
console.log(toWeirdCase('This is a test')); // 'ThIs Is A TeSt'
A string in javascript is immutable so you will need to do something like :
let test = 'This is a test';
test = toWeirdCase(test); //Here you assign the result
And here is an example solution which ignores spaces in the count
function toWeirdCase(string) {
let count = 0;
return string.split("").map((x) => {
if(x !== " ")
count++;
if(count%2 === 0) return x.toUpperCase();
else return x;
}).join("")
}
let test = 'This is a test';
test = toWeirdCase(test);
console.log(test); //THiS iS a TeSt
Like the comments mention, strings in Javascript are immutable. That being said, you can break down the input string on whitespace, do the transformations, and join back into a string, something like this -
function toWeirdCase(sentence) {
return sentence
.split(' ')
.map(word => word
.split('')
.map((c, i) => i % 2 ? c : c.toUpperCase())
.join('')).join(' ');
}
You could store the number of spaces in a variable in the functions scope.
function toWeirdCase(string) {
let spaceCount = 0;
// Personal preference: I like the reduce fn for this, but a similar thing could be achieved with map
return string.split('').reduce((value, letter, index) => {
if (letter === ' ') spaceCount++;
return value += ((index - spaceCount) % 2)
? letter
: letter.toUpperCase();
},'')
}
This returns the leter if the index ingoring the space count has a remainder when divided by 2.
You can achieve this like so:
const str = "this is a test";
function toWeirdCase(str) {
return str.split(" ").map(word => (
[...word].map((c, i) => i % 2 ?
c.toLowerCase() :
c.toUpperCase())).join("")).join(" ");
}
console.log(toWeirdCase(str));
Updated: to set odd indexes toLowerCase() to handle edge cases like acronyms (ie: currency acronyms; "CA", "USD")
Hope this helps,

(replace) CamelCase function not work properly

working with this function call:
var StringData = window.ToCamelCase({ 'string': 'HELLO WORLD', 'remSpace': false });
console.log(StringData);
and this is my script function:
function ToCamelCase(data) {
data['string'] = data['string'].replace(/(?:^\w|[A-Z]|\b\w)/g, function(word, index) {
return index == 0 ? word.toUpperCase() : word.toLowerCase();
});
if (data['remSpace']) {
data['string'] = data['string'].replace(/\s/g, '');
}
return data['string'];
}
i dont get error; but not work properly, if i passed and string like this:
"HELLO WORLD"
this moment second word not put first letter uppercase
the output is: "Hello world" and i expect: "Hello World"
First letter per word Upper Case and the following Lower Case is the rule.
what am I doing wrong?
You don't really need to use regex for this. You can split the string by using string.split(), then uppercase each element in the split array. Finally, recombine the array with spaces separating the elements if you want:
function ToCamelCase(data) {
const words = data['string'].toLowerCase().split(' ');
const uppercasedWords = words.map(word => {
let splitWord = word.split('');
splitWord[0] = splitWord[0].toUpperCase();
return splitWord.join('');
});
return uppercasedWords.join(data['remSpace'] ? '' : ' ')
}
or more functionally,
function uppercaseFirstElement(textArray) {
return [textArray[0].toUpperCase(), ...textArray.slice(1)];
}
function capitalizeWord(word) {
return uppercaseFirstElement(word.split('')).join('');
}
function toCamelCase(sentence, removeSpace) { // Really it should be `toPascalCase`
return sentence.toLowerCase().split(' ')
.map(capitalizeWord).join(removeSpace ? '' : ' ');
}
As mentioned by Ian, you do not need regular expressions for this job and it is probably more efficient to not use them.
That being said, if you DO want to make it work with a RegExp for whatever reason, you can use:
function toPascalCase(str) {
return str.replace(/(?:^|\s*)(\S+)(?:\s*|$)/g, (match, word) => word[0].toUpperCase() + word.slice(1).toLowerCase());
}
This code uses an es6 arrow function so you will need to change it if you want to be compatible with old browsers. This is also based on the spec I could get from your question but there are a lot of case non-handled regarding special characters outside of letters / numbers / whitespace range (they will be considered part of the words - it might be what you want though).
One last note: What you are trying to achieve is actually called PascalCase. In camelCase, the very first letter is lowercase.
First of all Ian's solution should be the correct one, since it is the simplest and understandable solution of them all.
If you are asking what's wrong with your code then my answer is this statement:
index == 0 ? word.toUpperCase() : word.toLowerCase()
is this statement what's causing all the problem. Your index is not 0 when it reaches to "W" of "World" so its going to make it lowercase.
Instead what you should be doing is capturing words and replace only the first letter of each word with an uppercase. Split method is a good solution, that's what Ian did. I have done something like this using the regex and replace, although its not necessary to do it like this.
function ToCamelCase(data) {
data['string'] = data['string'].replace(/(?:\s|^)(\w+)(?=\s|$)/g, function(word, index) {
var lowerWord = word.toLowerCase().trim();
return lowerWord.substring(0, 1).toUpperCase() + lowerWord.substring(1, word.length) + " "
});
if (data['remSpace']) {
data['string'] = data['string'].replace(/\s/g, '');
}
return data['string'];
}
In your code index will return always 0 as it is not iterating all your string characters
here I have tried with my code just replace with your code and let me know the result.
var StringData = window.toCamelCase({ 'string': 'HELLO WORLD', 'remSpace': false });
console.log(StringData);
function toCamelCase(data) {
var str = data['string'];
var isRemoveSpc = data['remSpace'];
var len = data['string'].length;
var newStr = "";
for(var i = 0; i < len; i++){
if( i == 0) {
newStr += str.charAt(i).toUpperCase();
} else if(str.charAt(i) == " ") {
if(isRemoveSpc) {
i++;
newStr += str.charAt(i).toUpperCase();
} else {
newStr += str.charAt(i);
i++;
newStr += str.charAt(i).toUpperCase();
}
} else {
newStr += str.charAt(i).toLowerCase();
}
}
return newStr;
}

How to remove specific character surrounding a string?

I have this string:
var str = "? this is a ? test ?";
Now I want to get this:
var newstr = "this is a ? test";
As you see I want to remove just those ? surrounding (in the beginning and end) that string (not in the middle of string). How can do that using JavaScript?
Here is what I have tried:
var str = "? this is a ? test ?";
var result = str.trim("?");
document.write(result);
So, as you see it doesn't work. Actually I'm a PHP developer and trim() works well in PHP. Now I want to know if I can use trim() to do that in JS.
It should be noted I can do that using regex, but to be honest I hate regex for this kind of jobs. Anyway is there any better solution?
Edit: As this mentioned in the comment, I need to remove both ? and whitespaces which are around the string.
Search for character mask and return the rest without.
This proposal the use of the bitwise not ~ operator for checking.
~ is a bitwise not operator. It is perfect for use with indexOf(), because indexOf returns if found the index 0 ... n and if not -1:
value ~value boolean
-1 => 0 => false
0 => -1 => true
1 => -2 => true
2 => -3 => true
and so on
function trim(s, mask) {
while (~mask.indexOf(s[0])) {
s = s.slice(1);
}
while (~mask.indexOf(s[s.length - 1])) {
s = s.slice(0, -1);
}
return s;
}
console.log(trim('??? this is a ? test ?', '? '));
console.log(trim('abc this is a ? test abc', 'cba '));
Simply use:
let text = '?? something ? really ??'
text = text.replace(/^([?]*)/g, '')
text = text.replace(/([?]*)$/g, '')
console.log(text)
A possible solution would be to use recursive functions to remove the unwanted leading and trailing characters. This doesn't use regular expressions.
function ltrim(char, str) {
if (str.slice(0, char.length) === char) {
return ltrim(char, str.slice(char.length));
} else {
return str;
}
}
function rtrim(char, str) {
if (str.slice(str.length - char.length) === char) {
return rtrim(char, str.slice(0, 0 - char.length));
} else {
return str;
}
}
Of course this is only one of many possible solutions. The function trim would use both ltrim and rtrim.
The reason that char is the first argument and the string that needs to be cleaned the second, is to make it easier to change this into a functional programming style function, like so (ES 2015):
function ltrim(char) {
(str) => {
<body of function>
}
}
// No need to specify str here
function ltrimSpaces = ltrim(' ');
Here is one way to do it which checks for index-out-of-bounds and makes only a single call to substring:
String.prototype.trimChars = function(chars) {
var l = 0;
var r = this.length-1;
while(chars.indexOf(this[l]) >= 0 && l < r) l++;
while(chars.indexOf(this[r]) >= 0 && r >= l) r--;
return this.substring(l, r+1);
};
Example:
var str = "? this is a ? test ?";
str.trimChars(" ?"); // "this is a ? test"
No regex:
uberTrim = s => s.length >= 2 && (s[0] === s[s.length - 1])?
s.slice(1, -1).trim()
: s;
Step-by-step explanation:
Check if the string is at least 2 characters long and if it is surrounded by a specific character;
If it is, then first slice it to remove the surrounding characters then trim it to remove whitespaces;
If not just return it.
In case you're weirded out by that syntax, it's an Arrow Function and a ternary operator.
The parenthesis are superfluous in the ternary by the way.
Example use:
uberTrim(''); // ''
uberTrim(' Plop! '); //'Plop!'
uberTrim('! ...What is Plop?!'); //'...What is Plop?'
Simple approach using Array.indexOf, Array.lastIndexOf and Array.slice functions:
Update: (note: the author has requested to trim the surrounding chars)
function trimChars(str, char){
var str = str.trim();
var checkCharCount = function(side) {
var inner_str = (side == "left")? str : str.split("").reverse().join(""),
count = 0;
for (var i = 0, len = inner_str.length; i < len; i++) {
if (inner_str[i] !== char) {
break;
}
count++;
}
return (side == "left")? count : (-count - 1);
};
if (typeof char === "string"
&& str.indexOf(char) === 0
&& str.lastIndexOf(char, -1) === 0) {
str = str.slice(checkCharCount("left"), checkCharCount("right")).trim();
}
return str;
}
var str = "???? this is a ? test ??????";
console.log(trimChars(str, "?")); // "this is a ? test"
to keep this question up to date using an ES6 approach:
I liked the bitwise method but when readability is a concern too then here's another approach.
function trimByChar(string, character) {
const first = [...string].findIndex(char => char !== character);
const last = [...string].reverse().findIndex(char => char !== character);
return string.substring(first, string.length - last);
}
Using regex
'? this is a ? test ?'.replace(/^[? ]*(.*?)[? ]*$/g, '$1')
You may hate regex but after finding a solution you will feel cool :)
Javascript's trim method only remove whitespaces, and takes no parameters. For a custom trim, you will have to make your own function. Regex would make a quick solution for it, and you can find an implementation of a custom trim on w3schools in case you don't want the trouble of going through the regex creation process. (you'd just have to adjust it to filter ? instead of whitespace
This in one line of code which returns your desire output:
"? this is a ? test ?".slice(1).slice(0,-1).trim();

Categories