How to convert string to camelCase without using RegEX - javascript

I'm trying to do a challenge which is converting all strings into camelCase but without using regex, only using the methods like(split, slice, replace, includes.. etc). Some words have spaces and should remove them. Here's the CODE and I'm really STUCK. NOTE: the user enters the STRING and when user clicks the button should return to the camelCase.
INPUT =>
//underscore_case
//first_name
//Some_Variable
// calculate_AGE
//delayed_departure
OUTPUT =>
//underscoreCase
//firstName
//someVariable
//calculateAge
//delayedDeparture
document.body.append(document.createElement('textarea'));
document.body.append(document.createElement('button'));
document.querySelector('button').addEventListener('click', function() {
const text = document.querySelector('textarea').value;
const row = text.split('\n');
let [...n] = '';
for (const theText of row) {
const lowerText = theText.toLowerCase().trim();
if (lowerText.includes('_')) {
n = lowerText.replace('_', ' ');
console.log([...n]);
}
}
});

Explanation of this simple algorithm:
Your input must have words that split by a certain character, as you need something to identify which part of the string is a word. Let's assume your string has words separated by '//' instead of spaces as you mentioned in the comments, and each of those words is split by '_'.
First you need to split all words in the string into an array, you can use the split() method in order to do that.
Then when iterating through each word, split it again with split() but this time with whatever identifies the different words, in our case it's _.
Iterate through each split words, if it's the first word lowercase it using toLowerCase() and add it to the new word variable, if not, lowercase it and capitalize the first letter.
And that's it. Here's the implementation:
const inputWithoutCamelCase = 'hello_world // HOW_ARE_YOU // foo_BAR'
function stringToCamelCase(string) {
const allNames = string.split('//')
let camelCasedString = '';
for (const name of allNames) {
camelCasedString += nameToCamelCaseHelper(name);
}
return camelCasedString;
}
function nameToCamelCaseHelper(word) {
const splittedName = word.split('_');
let camelCasedName = '';
for (let i = 0; i < splittedName.length; i++) {
if (i === 0) {
camelCasedName += splittedName[i].toLowerCase();
} else {
camelCasedName += capitalizeFirstLetter(splittedName[i].toLowerCase())
}
}
return camelCasedName;
}
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
stringToCamelCase(inputWithoutCamelCase) // helloWorld howAreYou fooBar

Related

How to remove the (.) in a string and then display every alphabetic character with a dot

I would like to have a a function who takes a string a parameter, removes the dots, loops trough every alphabetic character and display like this (A.B.C.) when input is (A..B..C) for example.
How can I build this function?
Here for I have the next function in mind, unfortunately is not working I get a output result like this (hfff) when input string is "h..f.ff", would like to have this output (H.F.F.F)
function filter (initials) {
let result = initials.replace(/\./g, '')
let i;
for (i = 0; i < result.length; i++) {
result[i] + ".";
}
return result
console.log(result)
}
const initials = "h..f.ff"
console.log(filter(initials))
You could use split, map and join
function filter(initials) {
return initials.replace(/[^a-z]/gi, '') // Remove non-letters
.toUpperCase()
.split('') // Convert to an Array
.map(l => l + '.') // Add dots
.join(''); // Join
}
const initials = "h..f.ff";
console.log(filter(initials));
You need to assign this
result[i] + ".";
to something. Do:
let i,newresult;
for (i = 0; i < result.length; i++) {
newresult += result[i] + ".";
}
well you can:
make the string uppercase
split the string char-by-char
filter only letters
join using "."
function format(string){
return string.toUpperCase()
.split("")
.filter(c => /[a-zA-Z]/.test(c))
.join(".")
}
format("h..f.ff") // "H.F.F.F"
Use replaceAll to remove all . char with nothing.
Then from that string, make all letters uppercase.
From that string, split the whole word up into and array of letters using split (Each piece of the string on each side of the parameter passed to split gets turned into an element in a new array. if you leave the parameter blank, it's just each character in the string)
Finally join each those elements together with a . between them using join
function filter (initials) {
initials=initials.replaceAll('.','');
initials=initials.toUpperCase();
initials=initials.split('');
initials=initials.join('.');
return initials;
}
var test = "h..f..t....e.Z";
console.log(filter(test));
Thanks #blex for the snippet advice

Group array with two words, rather than one

CODE BELOW: When a word has been written, it stores that as its own array, meaning every single word is its own array, and then later checked for reoccurrences.
What i want: Instead of it creating an array of a word (after spacebar has been hit), i want it to do it after 2 words have been written.
IE: Instead of me writing "Hello" + spacebar, and the code creating "hello" as an array. I'd like it to wait until i've written "hello my" + spacebar and then create an array with those two numbers.
I am guessing this has something to do with the regular expression?
I've tried many different things (a little bit of a newbie) and i cannot understand how to get it to group 2 words together rather than one.
const count = (text) => {
const wordRegex = new RegExp(`([\\p{Alphabetic}\]+)`, 'gu');
let result;
const words = {};
while ((result = wordRegex.exec(text)) !== null) {
const word = result[0].toLowerCase();
if (!words[word]) {
words[word] = [];
}
words[word].push(result.index);
words[word].push(result.index + word.length);
}
return words;
};
You may use
const wordRegex = /\p{Alphabetic}+(?:\s+\p{Alphabetic}+)?/gu;
Details
\p{Alphabetic}+ - 1+ alphabetic chars
(?:\s+\p{Alphabetic}+)? - an optional sequence of:
\s+ - 1+ whitespaces
\p{Alphabetic}+ - 1+ alphabetic chars
The second word is matched optionally so that the final odd word could be matched, too.
See the JS demo below:
const count = (text) => {
const wordRegex = /\p{Alphabetic}+(?:\s+\p{Alphabetic}+)?/gu;
let result;
const words = {};
while ((result = wordRegex.exec(text)) !== null) {
const word = result[0].toLowerCase();
if (!words[word]) {
words[word] = [];
}
words[word].push(result.index);
words[word].push(result.index + word.length);
}
return words;
};
console.log(count("abc def ghi"))
A RegExp constructor way of defining this regex is
const wordRegex = new RegExp("\\p{Alphabetic}+(?:\\s+\\p{Alphabetic}+)?", "gu");
However, since the pattern is static, no variables are used to build the pattern, you can use the regex literal notation as shown at the top of the answer.

How do I structure this new logic to fit into pre-existing code?

I have written a code that removes all consonants before a vowel from a string and replaces it with an 'r' and in the case, the string starts with a vowel it should return the word without doing anything to it. Now, I want to add two things I came up with to it but unfortunately, I have not been able to:
1. When the string input is all consonants then it should do nothing and just return the string.
2. If user types in space like so ' ' then it should be trimmed.
How do I place this logic in the code below without affecting what is already working?
const scoobyDoo = str => {
if(typeof str !== 'string'){
return 'This function accepts strings only';
}
let newStr = str.toLowerCase().split('');
let arrWord = newStr.length;
let regex = /[aeiou]/gi;
if (newStr[0].match(regex)){
let nothing = newStr.join('');
return nothing;
}
else {
for (let i = 0; i < arrWord; i++){
let vowelIndex = newStr.indexOf(str.match(regex)[i].toLowerCase());
newStr.splice(0, vowelIndex, 'r');
return newStr.join('');
}
}
}
console.log(scoobyDoo('scooby'));//works as expected returns 'rooby'
console.log(scoobyDoo('ethane'));//works as expected returns 'ethane'
console.log(scoobyDoo('why'));// should return 'why'
console.log(scoobyDoo(' '));// should return trimmed space and a
text telling the user only spaces were entered.
I realise this doesn't really answer your question, but your existing logic is very complicated and you could achieve the same result with String.trim, .toLowerCase and .replace:
console.log('scooby'.trim().toLowerCase().replace(/^(?=.*?[aeiou])[^aeiou]+/, 'r'))
rooby
console.log('ethane'.trim().toLowerCase().replace(/^(?=.*?[aeiou])[^aeiou]+/, 'r'))
ethane
console.log('why'.trim().toLowerCase().replace(/^(?=.*?[aeiou])[^aeiou]+/, 'r'))
why
console.log('*' + ' '.trim().toLowerCase().replace(/^(?=.*?[aeiou])[^aeiou]+/, 'r') + '*')
**
The regexp uses a positive lookahead to ensure that there is a vowel in the string, and if so replaces all leading consonants with an r.
To do something more in line with your existing function, you could try this. It still makes extensive use of regex functions though.
const scoobyDoo = str => {
if(typeof str !== 'string'){
return 'This function accepts strings only';
}
// is it a blank string?
if (str.match(/^\s+$/)) {
return '';
}
// does it start with a vowel? if so, nothing to do
if (str.match(/^[aeiou]/i)) {
return str;
}
// does it only contain consonants?
if (!str.match(/[aeiou]/i)) {
return str;
}
// must not start with a vowel but still include one
return str.replace(/^[^aeiou]+/i, 'r');
}

Bold part of String

What is the best way to bold a part of string in Javascript?
I have an array of objects. Each object has a name. There is also an input parameter.
If, for example, you write "sa" in input, it automatically searches in array looking for objects with names that contain "sa" string.
When I print all the names, I want to bold the part of the name that coincide with the input text.
For example, if I search for "Ma":
Maria
Amaria
etc...
I need a solution that doesn't use jQuery. Help is appreciated.
PD: The final strings are in the tag. I create a list using angular ng-repeat.
This is the code:
$scope.users = data;
for (var i = data.length - 1; i >= 0; i--) {
data[i].name=data[i].name.replace($scope.modelCiudad,"<b>"+$scope.modelCiudad+"</b>");
};
ModelCiudad is the input text content var. And data is the array of objects.
In this code if for example ModelCiudad is "ma" the result of each is:
<b>Ma</b>ria
not Maria
You can use Javascript's str.replace() method, where str is equal to all of the text you want to search through.
var str = "Hello";
var substr = "el";
str.replace(substr, '<b>' + substr + '</b>');
The above will only replace the first instance of substr. If you want to handle replacing multiple substrings within a string, you have to use a regular expression with the g modifier.
function boldString(str, substr) {
var strRegExp = new RegExp(substr, 'g');
return str.replace(strRegExp, '<b>'+substr+'</b>');
}
In practice calling boldString would looks something like:
boldString("Hello, can you help me?", "el");
// Returns: H<b>el</b>lo can you h<b>el</b>p me?
Which when rendered by the browser will look something like: Hello can you help me?
Here is a JSFiddle with an example: https://jsfiddle.net/1rennp8r/3/
A concise ES6 solution could look something like this:
const boldString = (str, substr) => str.replace(RegExp(substr, 'g'), `<b>${substr}</b>`);
Where str is the string you want to modify, and substr is the substring to bold.
ES12 introduces a new string method str.replaceAll() which obviates the need for regex if replacing all occurrences at once. It's usage in this case would look something like this:
const boldString = (str, substr) => str.replaceAll(substr, `<b>${substr}</b>`);
I should mention that in order for these latter approaches to work, your environment must support ES6/ES12 (or use a tool like Babel to transpile).
Another important note is that all of these approaches are case sensitive.
Here's a pure JS solution that preserves the original case (ignoring the case of the query thus):
const boldQuery = (str, query) => {
const n = str.toUpperCase();
const q = query.toUpperCase();
const x = n.indexOf(q);
if (!q || x === -1) {
return str; // bail early
}
const l = q.length;
return str.substr(0, x) + '<b>' + str.substr(x, l) + '</b>' + str.substr(x + l);
}
Test:
boldQuery('Maria', 'mar'); // "<b>Mar</b>ia"
boldQuery('Almaria', 'Mar'); // "Al<b>mar</b>ia"
I ran into a similar problem today - except I wanted to match whole words and not substrings. so if const text = 'The quick brown foxes jumped' and const word = 'foxes' than I want the result to be 'The quick brown <strong>foxes</strong> jumped'; however if const word = 'fox', than I expect no change.
I ended up doing something similar to the following:
const pattern = `(\\s|\\b)(${word})(\\s|\\b)`;
const regexp = new RegExp(pattern, 'ig'); // ignore case (optional) and match all
const replaceMask = `$1<strong>$2</strong>$3`;
return text.replace(regexp, replaceMask);
First I get the exact word which is either before/after some whitespace or a word boundary, and then I replace it with the same whitespace (if any) and word, except the word is wrapped in a <strong> tag.
Here is a version I came up with if you want to style words or individual characters at their index in react/javascript.
replaceAt( yourArrayOfIndexes, yourString/orArrayOfStrings )
Working example: https://codesandbox.io/s/ov7zxp9mjq
function replaceAt(indexArray, [...string]) {
const replaceValue = i => string[i] = <b>{string[i]}</b>;
indexArray.forEach(replaceValue);
return string;
}
And here is another alternate method
function replaceAt(indexArray, [...string]) {
const startTag = '<b>';
const endTag = '</b>';
const tagLetter = i => string.splice(i, 1, startTag + string[i] + endTag);
indexArray.forEach(tagLetter);
return string.join('');
}
And another...
function replaceAt(indexArray, [...string]) {
for (let i = 0; i < indexArray.length; i++) {
string = Object.assign(string, {
[indexArray[i]]: <b>{string[indexArray[i]]}</b>
});
}
return string;
}
Above solutions are great, but are limited! Imagine a test scenerio where you want to match case insensitive query in a string and they could be multiple matches.
For example
Query: ma
String: The Amazing Spiderman
Expected Result: The Amazing Spiderman
For above scenerio, use this:
const boldMatchText = (text,searchInput) => {
let str = text.toLowerCase();
const query = searchInput.toLowerCase();
let result = "";
let queryLoc = str.indexOf(query);
if (queryLoc === -1) {
result += text;
} else
do {
result += ` ${text.substr(0, queryLoc)}
<b>${text.substr(queryLoc, query.length)}</b>`;
str = str.substr(queryLoc + query.length, str.length);
text = text.substr(queryLoc + query.length, str.length);
queryLoc = str.indexOf(query);
} while (text.length > 0 && queryLoc !== -1);
return result + text;
};

Reverse words in array string matching punctuation in Javascript

How do I reverse the words in this string including the punctuation?
String.prototype.reverse = function () {
return this.split('').reverse().join('');
}
var str = "This is fun, hopefully.";
str.reverse();
Currently I am getting this:
".yllufepoh ,nuf si sihT"
When I want to return this:
"sihT si nuf, yllufepoh."
You could reverse each word instead of the whole string, but you have to keep spaces, periods etc seperate, so a word boundary is needed
String.prototype.reverse = function () {
return this.split(/\b/g).map(function(word) {
return word.split('').reverse().join('');
}).join('');
}
var str = "This is fun, hopefully.";
document.body.innerHTML = str.reverse();
Note that this moves the comma one space as it gets the comma and the space in one boundary and swaps them. If the comma needs to stay in the same spot, split on spaces as well, and change the regex to /(\b|\s)/g
Simply reversing the string wont give the solution.
Get each word.
Reverse It
Again rejoin
var str = "This is fun, hopefully.";
alert(str.split("").reverse().join("").split(" ").reverse().join(" "));
You can imagine that you receive a stream of letters and you have to construct words based on some separators (like: spaces, commas, dashes .etc).
While reading each character you keep constructing the word in reverse.
When you hit any separator you finished the word.
Now you just add it to the result and append the separator (this way the separators will not be put at the beginning of the word, but at the end).
Here is an example:
const inputString = "HELLO, Welcome to Google's meeting. My name is Jean-Piere... Bye";
console.log('Normal words: ', inputString);
const result = reverseWords(inputString);
console.log('Words reversed: ', result);
function reverseWords(str='', separators=' ,.-') {
let result = '';
let word = '';
for (const char of str) {
if (separators.includes(char)) {
result += word + char;
word = '';
} else {
word = char + word;
}
}
// Adds last remaining word, if there is no separator at the end.
result += word;
return result;
}
const str = "This is fun, hopefully.";
function reverseWords(str){
const tempArr= str.split(" ")
let reversedTempArr=''
for(let i=0; i<tempArr.length;i++){
let tempStr=''
for(let j=tempArr[i].length-1;j>=0;j--){
tempStr += tempArr[i][j]
}
reversedTempArr += tempStr+ " "
}
return reversedTempArr
}
console.log(reverseWords(str))
You can reverse each word in a string in squence by splitting that word in to an array of words and then reversing each word and storing it in a new array and then joining that array as shown below.
//1) Reverse words
function reverseWords(str) {
// Go for it
let reversed;
let newArray=[];
reversed = str.split(" ");
for(var i = 0;i<reversed.length; i++)
{
newArray.push(reversed[i].split("").reverse().join(""));
}
return newArray.join(" ");
}
let reversedString = reverseWords("This is fun, hopefully.");
console.log("This is the reversed string : ",reversedString);

Categories

Resources