JavaScript string converting to lower or uppercase - javascript

//1. input words beginning and ending with a vowel are preserved in lowercase
//2. input words beginning with vowels and ending in a non vowel are translated to uppercase
//3. input words beginning with a non vowel and ending with a vowel are translated to a capitalized word (only first letter is uppercase)
//4. when printing the words, only two vowels are preserved per word (the first two)
//Output "i dont know Dude i AM not typing ALL OF this Nonsens text"
var str = "i dont know dude i am not typing all of this nonsense text";
console.log(str);
var res = str.split(" ");
console.log(res);
for(let i = 0; i<res.length;i++){
//checking words after spliting into single words
if((res[i].split("") && (res[0] ==== 'a'|| 'e' || 'o' || 'u' || 'i' || 'y') && (/* last charachter to check */ ))
}
I am beginner JavaScript Developer and i am having some difficulties with my exercise i have above 4 conditions first i split the array into a words then i hoped to split into single characters so res[0] will be my first item . I dont know if this will work but at least i need to try. Any help will be very appreciated even if it is with regular expressions. Thank you

You can use reduce of Array.prototype.
var str = "i dont know dude i am not typing all of this nonsense text";
console.log(str);
var res = str.split(" ");
var y=res.reduce((a,e) => {
if("aeiou".includes(e[0])){ //condition 1 and 2
return a + ("aeiou".includes(e[e.length-1]) ? getWord(e).toLowerCase() : getWord(e).toUpperCase()) + " ";
}
else{ //condition 3
return a + ("aeiou".includes(e[e.length-1]) ? e[0].toUpperCase() + getWord(e.substr(1)).toLowerCase() : e) + " ";
}
},"");
function getWord(x){ //condition 4
var count = 0;
for(var i = 0; i < x.length; i++){
count += "aeiou".includes(x[i]) ? 1 : 0;
if(count === 3)
return x.substr(0,i);
}
return x;
}
console.log(y);

Here is a quick function that does fulfills 1 to 3. I'm not sure what you mean in 4.
Snippet:
/* Example. */
var str = "i dont knoooow dudeeeee i am not typing all of this nonsense text";
console.log(str);
console.log(process(str));
/* --------------------------------------------- */
/* The function that checks whether a char is a vowel. */
function isVowel (char) {
return "aeiou".includes(char);
}
/* The function that truncates a word before the 3rd vowel. */
function truncate (word) {
/* Create an index and a counter and save the length of the word. */
var i = 0, c = 0, l = word.length;
/* Iterate over every char until 3 vowels are found, if found. */
for (; i < l && c < 3; i++, c += +isVowel(word[i]));
/* Return the part of the string until before the 3rd vowel. */
return word.slice(0, i);
};
/* The function that processes the string. */
function process (str) {
/* Split the sentence into an array of words. */
var words = str.split(" ");
/* Iterate over every word. */
words.forEach(function (word, index) {
/* Strip any more than 2 repeated vowels and anything beyond the 3rd vowel. */
word = truncate(word.replace(/([aeiou])\1{2,}/i, "$1$1")); // 4
/* Check whether the first character is a vowel or not. */
words[index] = isVowel(word[0])
/* Check whether the last character is a vowel or not. */
? isVowel(word[word.length - 1])
? word.toLowerCase() // 1
: word.toUpperCase() // 2
/* Check whether the last character is a vowel or not. */
: isVowel(word[word.length - 1])
/* Capitalise the first char and turn the rest to lowercase. */
? word[0].toUpperCase() + word.slice(1).toLowerCase() // 3
: word;
});
/* Join the array into a string and return it. */
return words.join(" ");
}

res[0] ==== 'a'|| 'e'
That wont work. You need to do:
res[0] ==== 'a'|| res[0] === 'e'
However as that is quite complicated, might just do:
"aeiou".includes(res[0])
Oh and res[0] is the first word, not the first char, that would be res[i][0]. And you can get the last one with res[i][res[i].length - 1]. And i still dont get what you are trying to do with res[i].split("") && ... just leave that away.

Related

vowelFrequency JavaScript function

I need to iterate over an input string and return a string with the count of the frequency of the different vowels in the string. The vowels in the return string should be in the order they appear in the input string. So, if 'hello world' is the function's parameter, the function should return e1o2. The code I have so far is below. It returns e1o2o3. For some reason, it is not stopping the count of o after it hits the o in hello, and seems to be counting the o in world as a separate count. I think it is, finalString += char + sum;, that is causing this. But, I do not know how to create this function in the first place. Thank you for your time.
function vowelFrequency(str) {
let finalString = '';
let sum = 0;
for (let char of str) {
if ('aeiou'.includes(char)) {
sum += 1;
finalString += char + sum;
}
}
return finalString;
};
The main problem is your sum counter. It counts all vowels together.
Better appoach would be to create a dictionary of vowels
where we add +1 every time we met a match.
In short the idea is:
if (char === 'e') {
dic['e'] += 1;
}
const text = 'hello world';
function vowelFrequency(str) {
let finalString = '';
let dic = {};
for (let char of str) {
if ('aeiou'.includes(char)) {
//check if dictionary has no certain vowel
//it happens when we first time meet a vowel
if (!(char in dic)) {
dic[char] = 0;
}
//increment our counter
dic[char]+=1;
}
}
//by the end of the loop
//we have object with { e: 1, o: 2 }
//now we need to gather values into string
//loop through the object
for ([char, count] of Object.entries(dic)) {
finalString += char + count;
}
return finalString;
};
console.log(vowelFrequency(text));
Shorter version of the same solution would be:
function vowelFrequency(str) {
const vowels = 'aeiou';
let dic = [...str].reduce((dic, char) => {
if (vowels.includes(char))
dic[char] = dic[char] + 1 || 1;
return dic;
}, {});
return Object.entries(dic)
.map(([char, count]) => `${char}${count}`)
.join('');
};
One concise approach would be to transform the string via String.prototype.replaceAll (evaluating every character in the string). The following code searches the original string (which you may wish to normalize beforehand with .toLowerCase() for better results) for any character.
"hello world".replaceAll(/./g, ( char, index, str ) =>
!'aeiou'.includes( char ) || str.lastIndexOf( char ) > index
? "" : char + [ ...str ].filter( o => o == char ).length
);
Each character is checked against a list of vowels. We also check to see if the character index is the last index of this character (does it appear multiple times) in the original string. If either of these conditions fail, an empty string is returned in the character's place.
If our character is in our vowel list, and is the last instance of itself, then we split the original string, filter-out non-matching characters, and return the final count of character instances.
The above approach is somewhat of a gimmick. It's concise, but probably not very self-explanatory or maintainable. Realistically, you'd want to take a slightly more verbose approach (see below).
Note that Map is preferred over a standard object to ensure that key-insertion order is preserved.
function charInstanceString ( input, chars = "aeiou" ) {
/**
* Cycle over each character in our string, checking
* if it appears in our `chars` string. If the character
* appears in our `chars` string, we'll update our map
* to reflect the number of instances for the character.
*/
const charMap = new Map();
for ( const char of input ) {
if ( !chars.includes( char ) ) continue;
charMap.set( char, charMap.get( char ) + 1 || 1 );
}
/**
* Cycle over our map, adding each character (and its
* corresponding count) to an output string.
*/
let output = "";
for ( const [ char, count ] of charMap ) {
output += `${ char }${ count }`;
}
return output;
}

Javascript - Removing last 3 words from a string

I've been able to find examples of how to remove the last word of a string, but in this instance I'm attempting to remove the last 3 words of a string. I've attempted this by adjusting some of the answers I've come across to remove a single word but none have gave me the expected results.
Example string Highest ranked in the states
I would like my return value be Highest ranked
Here are some code snippets of what I've attempted:
let myString = "Highest ranked in the states";
myString = myString.substring(2, myString.lastIndexOf(" "));
console.log(myString)
let myString2 = "I want to remove the last word";
let mySplitResult2 = myString2.split(" ");
let lastWord = mySplitResult2[mySplitResult2.length-3]
console.log(lastWord)
with the adjusting the substring method to (2, myString.lastIndexOf(" ")); it ended up removing the first two letters of my sentence and only removed the word states such as "guest ranked in the"
when adjusting the .split() method to length -3 it simply returns back the word in instead of in the states
Here is a nice and readable one liner:
const remove3words = words => words.split(" ").slice(0, -3).join(" ");
console.log(remove3words("Highest ranked in the states"));
console.log(remove3words("Exactly three words"));
You can generalize it easily to n words in the following way:
function remove_n_words(words, n) {
return n === 0 ? words : words.split(" ").slice(0, -n).join(" ");
}
// Test the function
console.log(remove_n_words("Highest ranked in the states", 0));
console.log(remove_n_words("Highest ranked in the states", 3));
console.log(remove_n_words("Highest ranked in the states", 100));
let myString = "Highest ranked in the states";
myString = myString.split(' ')
myString = myString.splice(myString.length-5,2)
myString = myString.join(' ')
console.log(myString)
See comments for explanation using split and splice
let myString = "Highest ranked in the states";
//split the str using blank space between each word and add to new variable
let str = myString.split(" ");
//get the length
let num = str.length;
//splice the array removing the last three values with the number - 3
let newStr = str.splice(0, num - 3);
let displayText = '';
//back into string
newStr.forEach(function(value){
displayText += value + ' ';
});
display.textContent = displayText;
<div id="display"></div>
Here's a function that can do that for you. (It can actually remove all characters from the Nth-to-last occurrence of any character you specify, not just the Nth-to-last word.)
In your case:
the char parameter should get the value ' ' (ie spaces between words)
N should get the value 3 (to target the 3rd-to-last space)
I added an excludeChar parameter that you can set to true to avoid returning the final space (or you can use the .trim method on the result).
const
myString = "Highest ranked in the states",
result = truncateAtNthToLastOccurencOfChar(myString, ' ', 3);
console.log(result);
function truncateAtNthToLastOccurencOfChar(str, char, N, excludeChar){
// Makes counter, converts str to arr & reverses it
let i = -1, rev = Array.from(str).reverse();
// Increments counter (and executes even when i=0)
while(++i || true){
// Returns original string if at the end `char` has occured fewer than `N` times
if(i >= rev.length - 1){
return str;
}
// If current character matches `char`, decrements `N`
if(rev[i] == char && --N === 0){
// If N=0, `i` is our target, all keeps characters (from reversed array)
// starting at `i` (or after `i` if excludeChar=true)
return rev
// The occurence of char can be excluded from result
.slice(excludeChar ? (i + 1) : i)
.reverse() // Restores original character order
.join(''); // Converts back to string
}
}
}

Write a function which takes a sentence as an input and output a sorted sentence. (The answer should be valid for any given input.)

I want to write a function which takes a sentence as an input and output a sorted sentence, and there are two criterias:
Each character of the word should be arranged in alphabetical order.
Words should be arranged in ascending order depending on its character count.
Note: - Word only can have lowercase letters
Example :
Inputs str = "she lives with him in a small apartment"
Output = "a in ehs him hitw eilsv allms aaemnprtt"
Here is my code.
function makeAlphabetSentenceSort(str) {
if (!str || str.length === 0) return 0;
var word = str.split(' ');
for (var j = 0; j < word.length; j++) {
word[j] = word[j].split('').sort().join('');
}
for (var h = 0; h < word.length - 1; h++) {
for (var i = 0; i < word.length - h - 1; i++) {
if (String(word[i]).length > String(word[i + 1]).length) {
var temp = word[i];
word[i] = word[i + 1];
word[i + 1] = temp;
}
}
}
return word.join(' ');
}
makeAlphabetSentenceSort("she lives with him in a small apartment");
Based on the assumption that the output should contain only lowercase letters.
Well if you want to use the built-in functions you could also write that as:
function makeAlphabetSentenceSort(str) {
if (!str) return str;
const nonCharacters = /[^a-z]/g; // to replace any thing other than letters
// We split the sentence to words by any whitespace first
return str.toLowerCase().split(/\s+/).map(word => {
// Here we remove all non-characters from the word
// And sort the remaining characters alphabetically
return word.replace(nonCharacters, '').split('').sort().join('');
// It might be that the sentence looks like:
// "Hey! ???"
// In that case the "word" ??? would become just an empty string
// since all the non-characters have been removed.
// But then you would end up with a result:
// " ehy"
// because the empty word would still get added to the beginning of the sentence
// Because of that we need to filter the empty words out
// And to do that I use this lil trick of mine, using "Boolean"
// as a filter function since Boolean('') is false
// and Boolean('any word') is true
}).filter(Boolean).sort((a, b) => {
// Here we sort all the words by their length
return a.length - b.length;
}).join(' ');
}
console.log(makeAlphabetSentenceSort("Isn't it?"));
console.log(makeAlphabetSentenceSort("she lives with him in a small apartment"));

adding a space to every space in a string, then cycling back around until length is met

I have the following while loop as part of my text justify function. The idea is that I have text strings (str) that need to be justified (spaces added to existing spaces in between words) to equal to a given length (len)
The catch is I can only add one space to an existing space at a time before I iterate over to the next space in the string and add another space there. If that's it for all spaces in the string and it's still not at the required length, I cycle back over to the original space (now two spaces) and add another. Then it goes to the next space between words and so on and so on. The idea is that any spaces between words in the string should not have a differential of more than one space (i.e. Lorem---ipsum--dolor--sit, not Lorem----ipsum--dolor-sit)
From my research, I decided that using a substring method off the original string to add that first extra space, then I will increment the index and move to the next space in the string and repeat the add. Here's my code:
var indexOf = str.indexOf(" ", 0);
if ( indexOf > -1 ) {
while ( indexOf > -1 && str.length < len ) {
//using a regexp to find a space before a character
var space = /\s(?=\b)/.exec(str);
str = str.substring(0, indexOf + 1) + " " + str.substring(indexOf + 1);
//go to next space in string
indexOf = str.indexOf(space, indexOf + 2);
if ( indexOf === -1 ) {
//loops back to beginning of string
indexOf = str.indexOf(space, 0);
}
}
}
finalResults.push(str);
This code works most of the time, but I noticed that there are instances where the cycle of spacing is not correct. For example, it generates the following string:
sit----amet,--blandit
when the correct iteration would be
sit---amet,---blandit
Any assistance in making this code properly iterate over every space (to add one space) in the string once, then cycling back around to the beginning of the string to start over until the desired length is achieved would be most appreciated.
I think it's more efficient to compute the number spaces required in the beginning.
var s = "today is a friday";
var totalLength = 40;
var tokens = s.split(/\s+/);
var noSpaceLength = s.replace(/\s+/g,'').length;
var minSpace = Math.floor((totalLength - noSpaceLength)/(tokens.length-1));
var remainder = (totalLength - noSpaceLength) % (tokens.length-1);
var out = tokens[0];
for (var i = 1; i < tokens.length; i++) {
var spaces = (i <= remainder ? minSpace+1 : minSpace);
out += "-".repeat(spaces) + tokens[i];
}
$('#out').text(out);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="out"></div>
This solution
splits the string (s) into words in an array (a)
finds the number of spaces to be added between all words (add)
finds the remainder of spaces to be added between first words (rem)
then sticks the words with add spaces + one if rem is not exhausted
Code
var s = "Caballo sin Nombre"; // assume one space between words
var len = 21; // desired length
var need = len - s.length;
var a = s.split(/ /); // split s
// need>0 and at least two words
if (need > 0 && a.length>1) {
var add = Math.floor(need / (a.length-1)) + 1; // all spaces need that (+existing)
var rem = need % (a.length-1); // remainder
var sp = '';
while (add-- > 0) sp += ' ';
// replace
var i,res = ''; // result
for (i=0 ; i<a.length-1 ; i++) {
res += a[i] + sp;
if (rem-- > 0) res += ' '; // remainder
}
res += a[i];
s = res;
}
console.log("'" + s + "' is " + s.length + " chars long.");
This function adds the spaces using a global replace, carefully limiting the text size.
function expand (txt, colwidth) {
txt = txt.replace (/\s\s+/, ' '); // Ensure no multiple spaces in txt
for (var spaces = ' ', // Spaces to check for
limit = colwidth - txt.length; // number of additional spaces required
limit > 0; // do while limit is positive
spaces += ' ') // add 1 to spaces to search for
txt = txt.replace (RegExp (spaces, 'g'),
function (r) {
// If limit > 0 then add a space else do not.
return limit > 0 && --limit ? r + ' ' : r
});
return txt;
}
for (var w = 21; w--;) console.log (expand ('this is a test.', w));
Shows this on console:
this is a test.
this is a test.
this is a test.
this is a test.
14 this is a test.

Get current sentence by cursor/caret position

I have a string containing multiple sentences. I also have the current cursor/caret position.
I need to be able to extract the current sentence at the given cursor position.
For example, take this string:
This is the first sentence. And this is the second! Finally, this is the third sentence
If the current cursor position is 33 then the cursor is in the second sentence.
In which case, the result returned should be:
And this is the second!
I only need to use the standard sentence definers of .?!
Any help with this would be greatly appreciated.
Although I am expecting regex to be required, if there is a faster alternative using native methods I would be interested in that also.
Here is a way to achieve what you need: use String#split with /[?!.]/g to get an array of sentences and then iterate over the array to sum up the lengths of the sentences found, and if the index is smaller than the count, return the sentence.
function getSentenceByPos(idx, str) {
pos = 0;
array = str.split(/[?!.]/g);
for (var i=0; i<array.length; i++) {
pos += array[i].length + 1;
if (pos >= idx) {
return array[i];
}
}
}// 26 still 1 then `.`. 51 then `!` - 53 is 3rd sentence!
document.write(getSentenceByPos(53, "This is the first sentence. And this is the second! Finally, this is the third sentence"));
I wanted to add an answer that doesn't use regular expression to split up the
string because doing so is quite inefficient and would likely be very slow on
larger chunks of text.
The most efficient way to do it would probably be to use a couple of loops to search, requiring only 2 passes to find the ends of the sentence.
var sentenceFromPos = function (s, pos) {
var len = s.length,
start,
end,
char;
start = pos;
end = pos;
while (start >= 0) {
char = s.charAt(start);
if (char === '.' || char === '?' || char === '!') {
break;
}
start -= 1;
}
while (end < len) {
char = s.charAt(end);
if (char === '.' || char === '?' || char === '!') {
break;
}
end += 1;
}
return s.substring(start + 1, end + 1).trim();
};
var phrase = 'This is the first sentence. And this is the second! Finally, this is the third sentence';
console.log(sentenceFromPos(phrase, 10));
console.log(sentenceFromPos(phrase, 33));
console.log(sentenceFromPos(phrase, 53));
This function will respect cursors over the limits of the phrases (like ! or .)
function getPhrase(string, cursor) {
phrases = string.match(/.*?(!|\.|$)/g)
basecursor = 0;
phrase = phrases[0]
for(ii=0; ii<phrases.length-1; ii++) {
if (basecursor+phrases[ii].length<cursor) {
phrase = phrases[ii+1]
basecursor += phrases[ii].length
}
}
return(phrase)
}
string = "This is the first sentence. And this is the second! Finally, this is the third sentence"
cursor = 0
phrase = getPhrase(string, cursor)
document.write(phrase)

Categories

Resources