I'm trying to insert a randomly selected string into each instance of whitespace within another string.
var boom = 'hey there buddy roe';
var space = ' ';
var words = ['cool','rad','tubular','woah', 'noice'];
var random_words = words[Math.floor(Math.random()*words.length)];
for(var i=0; i<boom.length; i++) {
boom.split(' ').join(space + random_words + space);
}
Output comes to:
=> 'hey woah there woah buddy woah roe'
I am randomly selecting an item from the array, but it uses the same word for each instance of whitespace. I want a word randomly generated each time the loop encounters whitespace.
What I want is more like:
=> 'hey cool there noice buddy tubular roe'
Thanks for taking a look.
(This is beta for a Boomhauer twitter bot, excuse the variables / strings 😅)
Maybe you can use regex instead however, you are not seeing the result you desire because you are randomly selecting one word and then replacing all occurrences of a space with it.
The regular expression below replaces occurrences of a space with a dynamic value returned by a callback. You could compare this callback to your for-loop but instead, it's iterating over the spaces found and by doing so you can replace each occurrence with a 'unique' random word.
const boom = 'hey there buddy roe';
const words = ['cool', 'rad', 'tubular', 'woah', 'noice'];
const random = () => Math.floor(Math.random() * words.length);
let replace = boom.replace(/ /g, () => ` ${words[random()]} `);
console.log(replace);
The problem is, that random_words is set to a single word.
Try this instead:
var boom = 'hey there buddy roe';
var words = ['cool','rad','tubular','woah', 'noice'];
boom.replace(/ /g, (space)=> space + words[Math.floor(Math.random()*words.length)] + space);
To get the effect you desire, you need to do the word selecting inside the loop, not outside of it.
for(var i=0; i<boom.length; i++) {
// get a new number every loop
var random_words = words[Math.floor(Math.random()*words.length)];
boom.split(' ').join(space + random_words + space);
}
What is wrong with OP's code: random_words is initialized once only, with a random word. Intention there is, however, to select random word for every whitespace encountered instead.
You can either go with:
for(var i=0; i<boom.length; i++) {
boom.split(' ').join(space + words[Math.floor(Math.random()*words.length)] + space);
}
... or make random_words a function that returns a random word, then call it in your 'boom' loop. With every call, a new word selection will occur.
You need to recalculate the random word on each loop. Right now you have picked out a single random word, stored it in the random_words variable, and you reuse it each time. You could modify your code like this:
var boom = 'hey there buddy roe';
var space = ' ';
var words = ['cool','rad','tubular','woah', 'noice'];
function getRandomWord() {
return words[Math.floor(Math.random()*words.length)];
}
// Uses the same because the value given to join is not recalculated each time:
console.log(boom.split(' ').join(space + getRandomWord() + space));
// You could do this with a standard for loop:
let result = "";
let split = boom.split(' ')
for(var i=0; i<split.length; i++) {
result += split[i] + space;
if (i === split.length - 1) break;
result += getRandomWord() + space;
}
console.log(result);
// Or you can use a reduce:
let otherResult = boom.split(' ').reduce((res, word, index, split) => {
if (index === split.length - 1) return res + space + word;
return res + space + word + space + getRandomWord();
});
console.log(otherResult)
Related
I want to write a function where given an index it adds a <br> tag at every Ith index in string. If the index is a space we will insert a <br>, but if it's in the middle of a string we insert -<br>
I saw a lot of examples using a combination of regex and joins, but I wasnt sure how to do this since my join would be conditional.
For Example:
let my_string = "Here's a really really long string that I want to add breaks to at every 20th interval"
I'd like my function insert_break(my_string, 20) to return
Here's a really reall-<br>y long string that I<br> want to add breaks <br>to at every 20th interval
So far my function works at the first specified index, but I wasnt sure if I should write a loop or recursive function in order to get this to work at every index interval in the string (in the example at [20,60,40] and right now it just works at 20
Any help with the function appreciated:
insert_break = (str, index) => {
// mostly we'll need to hyphenate the new line
let breakword = "-<br>"
// but if there's a space before the index we dont
if (str[index] === " ") { breakword = "<br>" }
// I want this to run at every multiple of 20 within the string
// so I need some kind of for loop (or something recursive?)
// to add a <br> at every multiple of the index
if (index > 0) {
// this works if we only want to run this function ONCE at the index 20
//return str.substring(0, index) + breakword + str.substring(index)
let breakstring = str
for (let i = 1; i < Math.floor(str.length/index); i++) {
// 1*20, 2*20, 3*20
let idx = index*i
// this doesnt work.
// I need to add it to the new string, not write over the old one as I am here
breakstring = breakstring.substring(0, idx) + breakword + breakstring.substring(idx)
}
return breakstring
//return str.substring(0, index) + breakword + str.substring(index)
}
return breakword + str
}
Any help appreciated!
Loop over the string indexes in steps of index. Use substring() to extract each chunk of characters from the string, check its last character, and then append the appropriate form of <br>.
function insert_break(str, index) {
let result = "";
for (let i = 0; i < str.length; i += index) {
let chunk = str.substring(i, i + index);
if (chunk.endsWith(' ')) {
chunk += '<br>';
} else {
chunk += '-<br>';
}
result += chunk;
}
result = result.replace(/-?<br>$/, ''); // remove last `<br>`
return result;
}
let my_string = "Here's a really really long string that I want to add breaks to at every 20th interval";
console.log(insert_break(my_string, 20));
Indexes start at 0, not 1, so you need to use that as the initial value of i.
I created a function that given any string will return the string with the first and last letter of each word capitalized. So far it works in some words, not on others, can someone help me figure out why?
function Capitalize(str) {
var spl = str.split(" ");
var words = [];
for (let i = 0; i < spl.length; i++) {
//For every word
for (let j = 0; j < spl[i].length; j++) {
//For every letter in each word
var word = spl[i];
var size = spl[i].length;
var firstLetterCapital = word.replace(word[0], word[0].toUpperCase()); //Creates new array
var LastLetterCapital = firstLetterCapital.replace(
word[size - 1],
word[size - 1].toUpperCase()
);
}
words.push(LastLetterCapital);
}
console.log(words.join(" "));
}
Capitalize("hello there");
It works when I type : Capitalize("my name is john smith"), but not with Capitalize("hello there")
I know it's a complete mess and probably a very bad way to do it, but I started programming a month ago so give me a break :)
#symlink has already explained why it is "HellO ThEre" instead of "Hello TherE". He also has given a solution to explicitly target first and last character of the string. I have accomplished not much different than already posted by members, except for .. "may be" a little more explanation.
You can break the entire problem in these four steps.
Get all the words into an array.
Create a function, that takes each word and targets first and last character, changes it and returns the changed word.
Apply a mapping step using the function created above (in step 2) to the entire array of words (obtained in step 1).
Join the transformed array, obtained in step 3, using a blank space as a separator.
I have written two functions that accomplish this task. I am sorry for long name of functions. It helps me keep track of things in a complex program (especially when I am in a hurry!).
Step 2 function
function Capitalize_FirstAndLast_One_Word(word){
// Split the string in array for easy access/manipulation by indexing
Split_String = word.split("")
// Target the first word
Split_String[0] = Split_String[0].toUpperCase();
// Target the last word
Split_String[Split_String.length - 1] = Split_String[Split_String.length - 1].toUpperCase();
// Join the array into a single word
Joined_Back = Split_String.join("")
return Joined_Back;
}
Step 1, 3 and 4 function
function Capitalize_Entire_String(str){
Regular_Exp = new RegExp(/\w+/g);
//Below is step 1
MatchedArray = str.match(Regular_Exp);
//Below is step 3
ConvertedArray = MatchedArray.map(Capitalize_FirstAndLast_One_Word);
// Below is step 4
ReturnedString = ConvertedArray.join(" ");
console.log(ReturnedString);
return ReturnedString;
}
Now you have everything. You can use the function like below.
Capitalize_Entire_String("hello there");
Capitalize_Entire_String("hello there this is a test");
Hope this helps. I am sorry if this turned out to be a redundant answer for you.
Reason your code don't work is the use of replace(). replace() will always replace the first character found.
There is absolutely no reason to run a nested loop. You can achieve this using a single loop.
function cap(str){
let spl = str.split(' ');
for(let i = 0; i < spl.length; i++){
let temp = spl[i];
temp = temp[0].toUpperCase() + temp.slice(1)
temp = temp.slice(0,-1) + temp[temp.length - 1].toUpperCase();
spl[i] = temp;
}
return spl.join(' ');
}
console.log(cap("a quick brown fox"))
An easier way is to use map() and template strings.
const cap = str => str
.split(' ')
.map(x => (
x.length === 1 ?
x.toUpperCase() :
`${x[0].toUpperCase()}${x.slice(1,-1)}${x[x.length -1].toUpperCase()}`)
)
.join(' ')
console.log(cap("a quick brown fox"))
To simplify the function, you could split the string into an array, map each word to the desired format, and join it together into a string again.
function Capitalize(str){
return str.split(" ").map((word) => word.charAt(0).toUpperCase() +
(word.length > 2 ? word.substring(1, word.length - 1) : "") +
(word.length > 1 ? word.charAt(word.length - 1).toUpperCase() : "")).join(" ");
}
console.log(Capitalize("i want to capitalize first and last letters"));
Congrats on starting out programming...
You can use this to achieve what you want to do
function capitalizeFirstAndLastLetters (str) {
const words = str.split(" "); // Split the string into words
const modified = [];
for (const word of words) {
if (word.length <= 2) {
modified.push(word.toUpperCase()); // If the word less than 3 characters, the whole word is capitalized
continue;
}
var firstCapital = word[0].toUpperCase(); // word[0] gets the first index of the string (I.e. the first letter of the word)
var lastCapital = word.slice(-1).toUpperCase(); // The slice function slices a portion of the word. slice(-1) gets the last letter
var middlePart = word.slice(1, -1); // slice(1, -1) means start slicing from the second index (I.e. 1) and ignore the last index
modified.push(firstCapital + middlePart + lastCapital);
}
return modified.join(" "); // Join each element in the modified array with a space to get the final string with each words first and last letters capitalized
}
capitalizeFirstAndLastLetters("hello there I am a boy"); // "HellO TherE I AM A BoY"
Try this, it worked for hello world because I guess you want the outcome to be HellO TherE right?:
function capitalize(str) {
var spl = str.split(" ");
var words = [];
for (let i = 0; i < spl.length; i++) {
//For every word
let changedWord = "";
for (let j = 0; j < spl[i].length; j++) {
//For every letter in each word
if(j == 0 || j == spl[i].length - 1) {
changedWord += spl[i][j].toUpperCase();
} else {
changedWord += spl[i][j].toLowerCase();
}
}
words.push(changedWord);
console.log(words);
}
console.log(words.join(" "));
}
capitalize("hello there");
ALSO: Make your functions name start with lowercase letter. Thats just how it is. Starting with uppercase letters usually are Classes. Just a quick tip
Maybe this does what you want, don't want to change much from your code:
function Capitalize(str) {
var spl = str.split(" ");
var words = [];
for (let i = 0; i < spl.length; i++) {
var word = spl[i];
var firstCapital = word[0].toUpperCase(); // get first character after capitalizing
var lastCapital = word.slice(-1).toUpperCase(); // get last character after capitalizing
var midOriginal = word.slice(1, -1);
words.push(firstCapital + midOriginal + lastCapital) // concat 3 parts
}
console.log(words.join(" "));
}
Capitalize("hello there");
This expression:
var LastLetterCapital = firstLetterCapital.replace(
word[size - 1],
word[size - 1].toUpperCase()
);
Is replacing the first occurrence of the character "e" in "There" with an uppercase "E".
Explanation
The replace() function first translates the first param: word[size - 1] to the literal character "e", then replaces the first occurrence of that character with the uppercase "E", resulting in the string "ThEre".
Solution
Use a regular expression as your first parameter instead, to ensure that the last character is targeted, regardless of whether or not that same character shows up anywhere else in the word:
var LastLetterCapital = firstLetterCapital.replace(/.$/, word[size - 1].toUpperCase());
function Capitalize(str) {
var spl = str.split(" ");
var words = [];
for (let i = 0; i < spl.length; i++) {
//For every word
var word = spl[i];
var size = spl[i].length;
for (let j = 0; j < size; j++) {
//For every letter in each word
var firstLetterCapital = word.replace(word[0], word[0].toUpperCase()); //Creates new array
var LastLetterCapital = firstLetterCapital.replace(/.$/, word[size - 1].toUpperCase());
}
words.push(LastLetterCapital);
}
console.log(words.join(" "));
}
Capitalize("hello there");
This should do the trick:
function Capitalize(str) {
return str.replace(/(\b\w|\w\b)/g, l => l.toUpperCase())
}
console.log(Capitalize('i want to be capitalized in a rather strange way'))
Explanation:
In the regular expression /(\b\w|\w\b)/g, \b means "word boundary" and \w means "word character", so (\b\w|\w\b) matches a word boundary followed by a word character OR a word character followed by a word boundary (i.e. the first and last character of words).
The matches of this expression are then passed to the inline function l => l.toUpperCase() (which itself is the second argument to replace) that capitalizes the passed letter.
the string type is immutable, so why don't you try to convert the string to an array like y = word.split('') and do y[0] = word.charAt(0).toUpperCase() and then convert back to string with y.join('')
Say for example I have the words below
THIS TEXT IS A SAMPLE TEXT
I am given character index 7.
Then I have to return index 1 when I split the sentence into words which is the index of the word that contains the index of character not 5 which matches the word that composes the index of character exactly but not the correct index where character lies.
basically I am trying to return the correct word index of where character lies (when split into words) with character index (when split with characters)
I thought I would reconstruct the word with something like below to find the word at the character
let curString = 'find a word from here';
let initialPositin = 5
let position = initialPositin
let stringBuilder = '';
while(position > -1 && curString.charAt(position) !== ' '){
console.log('run 1')
console.log(position);
stringBuilder = curString.charAt(position) + stringBuilder;
position --;
}
console.log(stringBuilder)
position = initialPositin + 1;
while(position < curString.length && curString.charAt(position) !== ' '){
console.log('run 2')
stringBuilder += curString.charAt(position);
position ++;
}
console.log(stringBuilder);
Then split the sentence into words then find all the index of the word that contains the word that I have constructed. Then go through all the found words and reconstruct the previous words to see if the index of the target character in the reconstruction matches the character position given.
It doesn't really feel efficient. Does anyone have better suggestions?
I prefer javascript but I can try to translate any other language myself
I think you could just count spaces that occurs before given index, something like
let curString = 'find a word from here';
let givenIndex = 9;
let spaceIndex = 0;
for (var i = 0; i < curString.length; i++) {
if(curString.charAt(i) == ' ') {
if (i < givenIndex) {
spaceIndex++;
} else {
// found what we need
console.log(spaceIndex);
}
}
}
Maybe you could build a function that returns the position of all spaces.
Then you can see where the character index fits in that list of space positions.
text = "THIS TEXT IS A SAMPLE TEXT"
indexes = []
current_word = 0
for i in range(0, len(text)):
if text[i] == ' ':
current_word += 1 # After a ' ' character, we passed a word
else:
indexes.append(current_word) # current character belongs to current word
You can build indexes array for once with this piece of code(written in Python3) then you can use it for every indice. If you want to count ' ' characters in indexes array as well, you can simple add them in for loop(in if statement).
I ended up using below code
let content = 'THIS IS A SAMPLE SENTENCE';
let target = 13;
let spaceCount = 0;
let index = 0;
while(index < target) {
if (content.charAt(index) === ' ') {
spaceCount++;
}
index++;
}
let splitContent = content.split(' ');
splitContent[spaceCount] = '#' + value
console.log(splitContent.join(' '))
Worked very nicely
Just like the answer from #miradham this function counts the spaces before the given index, but with builtin functions to count character occurrences.
function wordIndexOfCharacterIndexInString(index, string) {
const stringUpToCharacter = string.slice(0, index)
return (stringUpToCharacter.match(/ /g) || []).length
}
console.log(wordIndexOfCharacterIndexInString(7, "THIS TEXT IS A SAMPLE TEXT"))
Please help me. I'm doing exercise and I don't understand what I'm doing wrong if all conditions execute. The task consists in returning the provided string with only the first letter of each word capitalized. My code performs this condition, but It doesn't get me ahead.
function titleCase(str) {
var text = str.toLowerCase();
var arr = text.split(" ");
var txt = " ";
var i;
for(i=0; i < arr.length; i++) {
txt += arr[i][0].toUpperCase() + arr[i].slice(1) + " " ;
}
return txt;
}
titleCase("sHoRt AnD sToUt");
You are adding extra whitespace (var txt = " " should be var text = ''), try this instead:
function titleCase(str) {
var text = str.toLowerCase();
// split on spaces, map over array and return capitalized word and join on space
return text.split(' ').map((word) => {
return word[0].toUpperCase() + word.slice(1);
}).join(' ');
}
alert(titleCase("sHoRt AnD sToUt"));
If your goal is to return the string back with the first letters capitalized, I can see one problem in your output. You should be returning
"Short And Stout"
but instead you return
" Short And Stout "
with a space before and after your string. You can fix this by initializing txt to an empty string rather than a space, and then either trimming the last space off at the end after your loop, or by only adding the space if you aren't on the last element of arr. That is:
var txt = "";
for(var i=0; i < arr.length; i++) {
txt += arr[i][0].toUpperCase() + arr[i].slice(1);
if (i != arr.length - 1) txt += " ";
}
You can use regular expression instead.
function titleCase(txt){
return txt.toLowerCase().replace(/\b\w/g, function(m){return m.toUpperCase();});
}
console.log(titleCase("sHoRt AnD sToUt"));//"Short And Stout"
Some explanation.
// regular expression (RegEx), g for global (else first only)
\b word boundary
\w any word symbol a-z (plus _)
m (function parameter) is match in the string
Having trouble coming up with code doing this.
So for example here is my string.
var str = "Hello how are you today?";
How would I manipulate this string to return the position of the first letter of each word using a loop?
this will give you the result with less complicated code and a single loop
function foo(str) {
var pos = [];
var words = str.split(' ');
pos.push(1);
var prevWordPos;
for (var i = 1; i < words.length; i++) {
prevWordPos = pos[i - 1] + words[i - 1].length;
pos.push((str.indexOf(words[i], prevWordPos) + 1));
}
return pos;
}
You should search for a question before asking it in case it's already been asked and answered.
Get first letter of each word in a string, in Javascript
You can use a regexp replace passing a function instead of a replacement string, this will call the function for each match:
str.replace(/[^ ]+/g, function(match, pos) {
console.log("Word " + match + " starts at position " + pos);
});
The regexp meaning is:
[^ ]: anything excluding space
+: one or more times
"g" option: not only first match, but each of them
in other words the function will be called with sequences of non-spaces. Of course you can define what you consider a "word" differently.
Here is a Solution with two Loops, i hope that is close enough ;)
var starts = [];
var str = "How are you doing today?";
//var count = 0;
var orgStr = str;
while (str.indexOf(" ") > 0) {
if (starts.length > 0) {
starts.push(starts[starts.length - 1] + str.indexOf(" ") +1);
} else {
starts.push(1);
starts.push(str.indexOf(" ") +2);
//alert(str);
}
str = str.substring(str.indexOf(" ") + 1);
}
for (var i = 0; i < starts.length; i++) {
alert(starts[i] + ": " + orgStr.substring(starts[i]-1,starts[i]))
}
Easiest would be to search a regular expression \b\w and collect match.start() match.index for each match. Loop while there's matches.
EDIT: wrong language. lol.