How does this replaceAt function work? - javascript

Could you please explain how this piece of code works?
String.prototype.replaceAt = function(index, character) {
return this.substr(0, index) + character + this.substr(index+character.length);
};
function titleCase(str) {
var newTitle = str.split(' ');
var updatedTitle = [];
for (var st in newTitle) {
updatedTitle[st] = newTitle[st].toLowerCase().replaceAt(0, newTitle[st].charAt(0).toUpperCase());
}
return updatedTitle.join(' ');
}
titleCase("I'm a little tea pot");
Specifically, what exactly is passed onto to replaceAt (I get that it's passed an index, and a character that's converted to lowercase), but what does replaceAt DO with it?
So, in the first iteration of the loop, it's passed replaceAt(0, i) right? Then what does replaceAt do with this? I just don't get this line:
this.substr(0, index) + character + this.substr(index+character.length)
I've already read this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr. I'm here because I don't understand that return statement and what exactly it's doing.

Suppose you execute "thisisatest".replaceAt(3, "h").
Then...
this.substr(0, index) returns "thi" : ie the first 3 characters of "thisisatest"
character returns "h"
this.substr(index+character.length) returns "isatest" : ie all characters of "thisisatest", starting at position 4
So, when you combine this, you get "thihisatest"

Lets imagine this easy case:
"0123456789". replaceAt(2/*index*/,"000"/*character*/)
Then this happens:
this.substr(0, index/*2*/)//"01"
+ character //"000"
+ this.substr(index/*2*/+character.length/*3*/)//"56789"
Output:
0100056789

The replaceAt function simply takes the index of a character (0 in this case) and replaces it with another character (in this case the uppercase version of the original character. This specific function is just Title Casing a word by replacing the first character with the same character in uppercase.
The line that your questioning, takes a substring of the word before the character at the specificied index this.substr(0,index) since substr is non-inclusive of the last index, appends the specified character + character, and appends a substr of the rest of the word + this.substr(index+character.length)
Example 'testing'.replaceAt(0,testing.charAt(0).toUpperCase());
= '' + 'T' + 'esting' = Testing;

this.substr is a function that operates on a string and returns a 'sub string' of the string. See a tutorial here: https://www.w3schools.com/jsref/jsref_substr.asp
So what replaceAt is doing is operating on a string and replacing the character at the target index, index, with the new substring, character. Indeed the passed character does not have to be only one character but could be multiple, like abcd. It is rather poorly named.
For more detail, using substr(), it is taking the first part of the string from index 0 to index, adding the 'character/string' passed to the function, and then taking the rest of the string from index index+character.length onwards. Note that substr has an optional parameter which is used in the first call (this.substr(0,index)).

Related

How do I replace the last letter of a string element in an array with replace()

I've just started coding..I'm a super beginner and have no idea about regex yet so for now I'd rather not use it. This is an exercise I'm trying to solve. The problem is that when a word contains matching characters, the first character gets the lower case, but what I actually want is the last character of the word to become small.
I don't really require a solution for the problem. Instead I'd rather have some insight on what I'm doing wrong and maybe direct me to the right path :)
function alienLanguage(str) {
let bigWords = str.toUpperCase().split(" ");
let lastLetterSmall = [];
bigWords.forEach(words => {
lastLetterSmall
.push(words
.replace(words
.charAt(words.length -1), words.charAt(words.length -1).toLowerCase()));
});
console.log(lastLetterSmall.join(' '));
}
alienLanguage("My name is John");
alienLanguage("this is an example");
alienLanguage("Hello World");
alienLanguage("HELLO WORLD");
Since you only really want to work with indicies of the string - you don't need to replace anything dynamically other than the last index - replace won't work well, since if you pass it a string, it will only replace the first matching letter. For example:
'foo'.replace('o', 'x')
results in 'fxo', because the first o (and only the first o) gets replaced.
For your code, instead of replace, just concatenate the two parts of the string together: the part from index 0 to next-to-last index, and the character at the last index with toLowerCase() called on it:
function alienLanguage(str) {
const result = str
.toUpperCase()
.split(" ")
.map(line => line.slice(0, line.length - 1) + line[line.length - 1].toLowerCase())
.join(' ');
console.log(result);
}
alienLanguage("My name is John");
alienLanguage("this is an example");
alienLanguage("Hello World");
alienLanguage("HELLO WORLD");

How do you create divs in javascript?

I am given a string as input, and the last letter in every word of the string should be capitalized, and then it is formed into their own div.
The one thing that I am finding tricky is that no matter what the string is there should always be enough divs to be separated, which to me means that I need to have a loop that generates it, which is what I am not sure how to write that logic.
I need this to be the output:
<div>
partY
</div>
<div>
likE
</div>
<div>
itS
</div>
<div>
2015
</div>
This is what I have so far:
function yay (input) {
input = input.toLowerCase().split("").reverse().join("").split(" ");
for(var i = 1 ; i < input.length ; i++){
var len = input[i].length-1;
input[i] = input[i].substring(0, len) + input[i].substr(len).toUpperCase();
}
return input .reverse().join(" ");
}
console.log(yay("Party like its 2015"));
Well, just a few minor changes to your code, which was on the right track... I basically removed the unnecessary reversing and wrapped each word in a div in the loop and viola:
function yay (input) {
input = input.toLowerCase().split(" ");
for(var i = 0 ; i < input.length ; i++){
var len = input[i].length-1;
input[i] = '<div>'+input[i].substring(0, len) + input[i].substr(len).toUpperCase()+'</div>';
}
return input.join("");
}
console.log(yay("Party like its 2015"));
document.write(yay("Party like its 2015"));
Output:
<div>partY</div><div>likE</div><div>itS</div><div>2015</div>
You can use document.createElement('div') and document.createTextNode('text') to simply get what you need.
You can return the content element directly to append to your node of your need, or you can use the innerHTML to do some text manipulations.
EDIT
Modified, I totally missed the last character needs to be uppercase
function yay(str) {
var arr = str.split(' ');
var content = document.createElement('div');
for(var part in arr) {
var sub = document.createElement('div');
var lastChar = arr[part].charAt(arr[part].length-1).toUpperCase();
var appendStr = arr[part].substring(0,arr[part].length-1);
sub.appendChild(document.createTextNode(appendStr+lastChar));
content.appendChild(sub);
}
return content.innerHTML;
}
console.log(yay("Party like its 2015"));
How about this:
function capitalizeLastLetter(input) {
return input.substring(0, input.length - 1) + input.charAt(input.length - 1).toUpperCase();
}
function yay(input) {
return input
.toLocaleLowerCase()
.split(" ")
.map(function(s){ return "<div>" + capitalizeLastLetter(s) + "</div>"; })
.join("");
}
console.log(yay("Party like its 2015"));
document.write(yay("Party like its 2015"));
Remixes this answer on how to capitalize the first letter of a word.
Add newlines where appropriate if you actually need those in your output.
You might want to use String.prototype.replace and feed it with a regular expression:
function yay(input) {
return input.
toLocaleLowerCase().
replace(/([^\s.,:;!?]*)([^\s.,:;!?")])([^\s]*)/g,
function(match, sub1, sub2, sub3) {
return '<div>' + sub1 + sub2.toLocaleUpperCase() + sub3 + '</div>';
});
}
The regex captures zero or more (because regular expressions are "greedy" by default, the algorithm will capture as many characters as it can) non-whitespace (to support alphabets other than Latin) and non-punctuation characters and exactly one non-whitespace/non-punctuation character following them (the last letter in the word, even if it's the only letter forming the word). The last group is zero or more of the previously specified punctuation marks (.,:;!?")). What it says is "non-whitespace character", but the presence of the two previous parenthesized groups implies that it must be a punctuation mark.
The replacement callback here uses four arguments, one (unused in this case) for the entire match and three for submatches corresponding to the parenthesized groups in the regex.
The value returned from the callback replaces the entire match in each successive replacement cycle (abcd in abcd efgh will be replaced with <div>abcD</div> and so on, note that whitespaces will be preserved).
In the callback function, the first submatch consists of all the letters in a word except the last one. It is returned as is, but the other match (which is the last letter) is capitalized. Optionally, a punctuation mark is appended if present in the original input. Everything is then wrapped in the <div> HTML tag and returned.
You can assign the value returned by the yay function to the innerHTML property of an HTML element, for example:
document.querySelector('#container').innerHTML = yay('Party like its 2015');
Spaces present in the input will remain. There is no need to replace them with new line characters, as all whitespaces are treated equally in HTML and will result in the same behavior.
Edit:
Now you can pass input containing punctuation to the function. The following line:
yay('Hello there, how about using some punctuation? "Quote" (Parentheses) ("What?")')
will result in:
'<div>hellO</div> <div>therE,</div> <div>hoW</div> <div>abouT</div> <div>usinG</div> <div>somE</div> <div>punctuatioN?</div> <div>"quotE"</div> <div>(parentheseS)</div> <div>("whaT?")</div>'

Remove (n)th space from string in JavaScript

I am trying to remove some spaces from a few dynamically generated strings. Which space I remove depends on the length of the string. The strings change all the time so in order to know how many spaces there are, I iterate over the string and increment a variable every time the iteration encounters a space. I can already remove all of a specific type of character with str.replace(' ',''); where 'str' is the name of my string, but I only need to remove a specific occurrence of a space, not all the spaces. So let's say my string is
var str = "Hello, this is a test.";
How can I remove ONLY the space after the word "is"? (Assuming that the next string will be different so I can't just write str.replace('is ','is'); because the word "is" might not be in the next string).
I checked documentation on .replace, but there are no other parameters that it accepts so I can't tell it just to replace the nth instance of a space.
If you want to go by indexes of the spaces:
var str = 'Hello, this is a test.';
function replace(str, indexes){
return str.split(' ').reduce(function(prev, curr, i){
var separator = ~indexes.indexOf(i) ? '' : ' ';
return prev + separator + curr;
});
}
console.log(replace(str, [2,3]));
http://jsfiddle.net/96Lvpcew/1/
As it is easy for you to get the index of the space (as you are iterating over the string) , you can create a new string without the space by doing:
str = str.substr(0, index)+ str.substr(index);
where index is the index of the space you want to remove.
I came up with this for unknown indices
function removeNthSpace(str, n) {
var spacelessArray = str.split(' ');
return spacelessArray
.slice(0, n - 1) // left prefix part may be '', saves spaces
.concat([spacelessArray.slice(n - 1, n + 1).join('')]) // middle part: the one without the space
.concat(spacelessArray.slice(n + 1)).join(' '); // right part, saves spaces
}
Do you know which space you want to remove because of word count or chars count?
If char count, you can Rafaels Cardoso's answer,
If word count you can split them with space and join however you want:
var wordArray = str.split(" ");
var newStr = "";
wordIndex = 3; // or whatever you want
for (i; i<wordArray.length; i++) {
newStr+=wordArray[i];
if (i!=wordIndex) {
newStr+=' ';
}
}
I think your best bet is to split the string into an array based on placement of spaces in the string, splice off the space you don't want, and rejoin the array into a string.
Check this out:
var x = "Hello, this is a test.";
var n = 3; // we want to remove the third space
var arr = x.split(/([ ])/); // copy to an array based on space placement
// arr: ["Hello,"," ","this"," ","is"," ","a"," ","test."]
arr.splice(n*2-1,1); // Remove the third space
x = arr.join("");
alert(x); // "Hello, this isa test."
Further Notes
The first thing to note is that str.replace(' ',''); will actually only replace the first instance of a space character. String.replace() also accepts a regular expression as the first parameter, which you'll want to use for more complex replacements.
To actually replace all spaces in the string, you could do str.replace(/ /g,""); and to replace all whitespace (including spaces, tabs, and newlines), you could do str.replace(/\s/g,"");
To fiddle around with different regular expressions and see what they mean, I recommend using http://www.regexr.com
A lot of the functions on the JavaScript String object that seem to take strings as parameters can also take regular expressions, including .split() and .search().

How can I remove a character from a string using JavaScript?

I am so close to getting this, but it just isn't right.
All I would like to do is remove the character r from a string.
The problem is, there is more than one instance of r in the string.
However, it is always the character at index 4 (so the 5th character).
Example string: crt/r2002_2
What I want: crt/2002_2
This replace function removes both r
mystring.replace(/r/g, '')
Produces: ct/2002_2
I tried this function:
String.prototype.replaceAt = function (index, char) {
return this.substr(0, index) + char + this.substr(index + char.length);
}
mystring.replaceAt(4, '')
It only works if I replace it with another character. It will not simply remove it.
Any thoughts?
var mystring = "crt/r2002_2";
mystring = mystring.replace('/r','/');
will replace /r with / using String.prototype.replace.
Alternatively you could use regex with a global flag (as suggested by Erik Reppen & Sagar Gala, below) to replace all occurrences with
mystring = mystring.replace(/\/r/g, '/');
EDIT:
Since everyone's having so much fun here and user1293504 doesn't seem to be coming back any time soon to answer clarifying questions, here's a method to remove the Nth character from a string:
String.prototype.removeCharAt = function (i) {
var tmp = this.split(''); // convert to an array
tmp.splice(i - 1 , 1); // remove 1 element from the array (adjusting for non-zero-indexed counts)
return tmp.join(''); // reconstruct the string
}
console.log("crt/r2002_2".removeCharAt(4));
Since user1293504 used the normal count instead of a zero-indexed count, we've got to remove 1 from the index, if you wish to use this to replicate how charAt works do not subtract 1 from the index on the 3rd line and use tmp.splice(i, 1) instead.
A simple functional javascript way would be
mystring = mystring.split('/r').join('/')
simple, fast, it replace globally and no need for functions or prototypes
There's always the string functions, if you know you're always going to remove the fourth character:
str.slice(0, 4) + str.slice(5, str.length)
Your first func is almost right. Just remove the 'g' flag which stands for 'global' (edit) and give it some context to spot the second 'r'.
Edit: didn't see it was the second 'r' before so added the '/'. Needs \/ to escape the '/' when using a regEx arg. Thanks for the upvotes but I was wrong so I'll fix and add more detail for people interested in understanding the basics of regEx better but this would work:
mystring.replace(/\/r/, '/')
Now for the excessive explanation:
When reading/writing a regEx pattern think in terms of: <a character or set of charcters> followed by <a character or set of charcters> followed by <...
In regEx <a character or set of charcters> could be one at a time:
/each char in this pattern/
So read as e, followed by a, followed by c, etc...
Or a single <a character or set of charcters> could be characters described by a character class:
/[123!y]/
//any one of these
/[^123!y]/
//anything but one of the chars following '^' (very useful/performance enhancing btw)
Or expanded on to match a quantity of characters (but still best to think of as a single element in terms of the sequential pattern):
/a{2}/
//precisely two 'a' chars - matches identically as /aa/ would
/[aA]{1,3}/
//1-3 matches of 'a' or 'A'
/[a-zA-Z]+/
//one or more matches of any letter in the alphabet upper and lower
//'-' denotes a sequence in a character class
/[0-9]*/
//0 to any number of matches of any decimal character (/\d*/ would also work)
So smoosh a bunch together:
var rePattern = /[aA]{4,8}(Eat at Joes|Joes all you can eat)[0-5]+/g
var joesStr = 'aaaAAAaaEat at Joes123454321 or maybe aAaAJoes all you can eat098765';
joesStr.match(rePattern);
//returns ["aaaAAAaaEat at Joes123454321", "aAaAJoes all you can eat0"]
//without the 'g' after the closing '/' it would just stop at the first match and return:
//["aaaAAAaaEat at Joes123454321"]
And of course I've over-elaborated but my point was simply that this:
/cat/
is a series of 3 pattern elements (a thing followed by a thing followed by a thing).
And so is this:
/[aA]{4,8}(Eat at Joes|Joes all you can eat)[0-5]+/
As wacky as regEx starts to look, it all breaks down to series of things (potentially multi-character things) following each other sequentially. Kind of a basic point but one that took me a while to get past so I've gone overboard explaining it here as I think it's one that would help the OP and others new to regEx understand what's going on. The key to reading/writing regEx is breaking it down into those pieces.
Just fix your replaceAt:
String.prototype.replaceAt = function(index, charcount) {
return this.substr(0, index) + this.substr(index + charcount);
}
mystring.replaceAt(4, 1);
I'd call it removeAt instead. :)
For global replacement of '/r', this code worked for me.
mystring = mystring.replace(/\/r/g,'');
This is improvement of simpleigh answer (omit length)
s.slice(0, 4) + s.slice(5)
let s = "crt/r2002_2";
let o = s.slice(0, 4) + s.slice(5);
let delAtIdx = (s, i) => s.slice(0, i) + s.slice(i + 1); // this function remove letter at index i
console.log(o);
console.log(delAtIdx(s, 4));
let str = '1234567';
let index = 3;
str = str.substring(0, index) + str.substring(index + 1);
console.log(str) // 123567 - number "4" under index "3" is removed
return this.substr(0, index) + char + this.substr(index + char.length);
char.length is zero. You need to add 1 in this case in order to skip character.
Maybe I'm a noob, but I came across these today and they all seem unnecessarily complicated.
Here's a simpler (to me) approach to removing whatever you want from a string.
function removeForbiddenCharacters(input) {
let forbiddenChars = ['/', '?', '&','=','.','"']
for (let char of forbiddenChars){
input = input.split(char).join('');
}
return input
}
Create function like below
String.prototype.replaceAt = function (index, char) {
if(char=='') {
return this.slice(0,index)+this.substr(index+1 + char.length);
} else {
return this.substr(0, index) + char + this.substr(index + char.length);
}
}
To replace give character like below
var a="12346";
a.replaceAt(4,'5');
and to remove character at definite index, give second parameter as empty string
a.replaceAt(4,'');
If it is always the 4th char in yourString you can try:
yourString.replace(/^(.{4})(r)/, function($1, $2) { return $2; });
It only works if I replace it with another character. It will not simply remove it.
This is because when char is equal to "", char.length is 0, so your substrings combine to form the original string. Going with your code attempt, the following will work:
String.prototype.replaceAt = function (index, char) {
return this.substr(0, index) + char + this.substr(index + 1);
// this will 'replace' the character at index with char ^
}
DEMO
You can use this: if ( str[4] === 'r' ) str = str.slice(0, 4) + str.slice(5)
Explanation:
if ( str[4] === 'r' )
Check if the 5th character is a 'r'
str.slice(0, 4)
Slice the string to get everything before the 'r'
+ str.slice(5)
Add the rest of the string.
Minified: s=s[4]=='r'?s.slice(0,4)+s.slice(5):s [37 bytes!]
DEMO:
function remove5thR (s) {
s=s[4]=='r'?s.slice(0,4)+s.slice(5):s;
console.log(s); // log output
}
remove5thR('crt/r2002_2') // > 'crt/2002_2'
remove5thR('crt|r2002_2') // > 'crt|2002_2'
remove5thR('rrrrr') // > 'rrrr'
remove5thR('RRRRR') // > 'RRRRR' (no change)
If you just want to remove single character and
If you know index of a character you want to remove, you can use following function:
/**
* Remove single character at particular index from string
* #param {*} index index of character you want to remove
* #param {*} str string from which character should be removed
*/
function removeCharAtIndex(index, str) {
var maxIndex=index==0?0:index;
return str.substring(0, maxIndex) + str.substring(index, str.length)
}
I dislike using replace function to remove characters from string. This is not logical to do it like that. Usually I program in C# (Sharp), and whenever I want to remove characters from string, I use the Remove method of the String class, but no Replace method, even though it exists, because when I am about to remove, I remove, no replace. This is logical!
In Javascript, there is no remove function for string, but there is substr function. You can use the substr function once or twice to remove characters from string. You can make the following function to remove characters at start index to the end of string, just like the c# method first overload String.Remove(int startIndex):
function Remove(str, startIndex) {
return str.substr(0, startIndex);
}
and/or you also can make the following function to remove characters at start index and count, just like the c# method second overload String.Remove(int startIndex, int count):
function Remove(str, startIndex, count) {
return str.substr(0, startIndex) + str.substr(startIndex + count);
}
and then you can use these two functions or one of them for your needs!
Example:
alert(Remove("crt/r2002_2", 4, 1));
Output: crt/2002_2
Achieving goals by doing techniques with no logic might cause confusions in understanding of the code, and future mistakes, if you do this a lot in a large project!
The following function worked best for my case:
public static cut(value: string, cutStart: number, cutEnd: number): string {
return value.substring(0, cutStart) + value.substring(cutEnd + 1, value.length);
}
The shortest way would be to use splice
var inputString = "abc";
// convert to array and remove 1 element at position 4 and save directly to the array itself
let result = inputString.split("").splice(3, 1).join();
console.log(result);
This problem has many applications. Tweaking #simpleigh solution to make it more copy/paste friendly:
function removeAt( str1, idx) {
return str1.substr(0, idx) + str1.substr(idx+1)
}
console.log(removeAt('abbcdef', 1)) // prints: abcdef
Using [index] position for removing a specific char (s)
String.prototype.remplaceAt = function (index, distance) {
return this.slice(0, index) + this.slice(index + distance, this.length);
};
credit to https://stackoverflow.com/users/62576/ken-white
So basically, another way would be to:
Convert the string to an array using Array.from() method.
Loop through the array and delete all r letters except for the one with index 1.
Convert array back to a string.
let arr = Array.from("crt/r2002_2");
arr.forEach((letter, i) => { if(letter === 'r' && i !== 1) arr[i] = "" });
document.write(arr.join(""));
In C# (Sharp), you can make an empty character as '\0'.
Maybe you can do this:
String.prototype.replaceAt = function (index, char) {
return this.substr(0, index) + char + this.substr(index + char.length);
}
mystring.replaceAt(4, '\0')
Search on google or surf on the interent and check if javascript allows you to make empty characters, like C# does. If yes, then learn how to do it, and maybe the replaceAt function will work at last, and you'll achieve what you want!
Finally that 'r' character will be removed!

Acronym generator in javascript. It only grabs the first letter of the first word, but the not the other words

Am I missing something in my code? It seems to only grab the first letter, and the while loop, doesn't go onto the next word. So what could I be missing?
function acr(s){
var words, acronym, nextWord;
words = s.split();
acronym= "";
index = 0
while (index<words.length) {
nextWord = words[index];
acronym = acronym + nextWord.charAt(0);
index = index + 1 ;
}
return acronym
}
If you only care about IE9+ then the answer can be made shorter:
function acronym(text) {
return text
.split(/\s/)
.reduce(function(accumulator, word) {
return accumulator + word.charAt(0);
}, '');
}
console.log(acronym('three letter acronym'));
If you can use arrow functions then it can be made shorter still:
function acronym(text) {
return text
.split(/\s/)
.reduce((accumulator, word) => accumulator + word.charAt(0), '');
}
console.log(acronym('three letter acronym'));
Add the separator to the split:
function acr(s){
var words, acronym, nextWord;
words = s.split(' ');
acronym= "";
index = 0
while (index<words.length) {
nextWord = words[index];
acronym = acronym + nextWord.charAt(0);
index = index + 1 ;
}
return acronym
}
JS Fiddle demo;
Revised the above to make it a little more demonstrative, and also interactive: JS Fiddle demo.
Edited to add references and explanation:
Because no separator was supplied the string remains un-split; therefore the while was operating correctly (as words.length is equal to 1), and so returns only the first letter of the string:
[Separator] specifies the character to use for separating the string. The separator is treated as a string or a regular expression. If separator is omitted, the array returned contains one element consisting of the entire string.
Reference:
split(), at MDC Docs
You forgot to split on whitespace:
words = s.split(/\s/);
You can have this in even lesser code. Try this
s.match(/\b(\w)/g).join("").toUpperCase()

Categories