Why is there such a difference between "" and " " in .split()? - javascript

So I have this code
function upperCase (text) {
let arr = text.split(" ");
let arr2 = [];
for(i = 0; i < arr.length; i++) {
arr2.push(arr[i].charAt(0).toUpperCase()+arr[i].slice(1));
}
return arr2.join(" ");
}
console.log(upperCase("something something"));
The current output is Something Something. But if I change the values in both .join() from .join(" ") to .join(""), the output is all capitalized (SOMETHING SOMETHING). I dont understand why does this happen? How does one space between "" make all characters capitalized?

split(" ") splits it into "something","something"
split("") splits it into "s","o","m","e","t","h","i","n","g", "s","o","m","e","t","h","i","n","g"
The uppercasing is done because you operate on lots of 1 element lists in the second case and every one gets its first character uppercased.

The parameter of split() states the character on witch the string is split. So if you provide a blank space " " your string will split on every "word".
But if you provide no character at all with "", the string will get split on every position, like Patrick Artner pointed out.
You could also split on comma "," or semicolon ";" or anything else.

Related

Search in string and quote around occurrence

Working with Javascript I need to be able to search a string input from a user and replace occurrences of semicolons with commas. Issue I have ran into is I need to be able to search the string for any commas that already exist, and quote around to the last and next occurrence of the semicolon.
Example:
User input is 12345;Joran,Michael;02;17;63 it should be converted to 12345,"Joran,Michael",02,17,63
My includes is able to locate the occurrence of a comma in the original string var srch = source.includes(","); and my replace is var converted = source.replace(/;/g, ","); which works fine, just need to figure out how to get to the last/next semicolon to place the quotes.
Using an if/else depending on if srch evaluates to True -- if true, add the quotes and then convert the rest of the string and return to the user; if false, convert and return.
I'm sure there's a way to do this with regex that just hasn't came to me yet so any suggestions on what to look at would be great.
I'd do this in two steps. First match non-; characters which have at least one ,, and surround them with quotes. Then replace all ;s in the result with ,:
console.log(
'12345;Joran,Michael;02;17;63'
.replace(/[^;,]*,[^;]*/g, '"$&"')
.replace(/;/g, ',')
);
Split the string by ;
.split(';')
which gives you an array.
Convert the elements that include a ',' to "${element}"
.map(s => s.includes(',') ? `"${s}"` : s )
Convert the array back to string
.join(',')
var str = '12345;Joran,Michael;02;17;63';
var arr = str.split(";");
var letters = /^[A-Za-z]/;
var final_str = "";
for (var i = 0; i < arr.length; i++) {
final_str = arr[i].match(letters)?final_str +'"'+ arr[i]+'"'+",":final_str + arr[i]+",";
}
console.log(final_str.substring(0,final_str.length -1));

Add letter before space in string

I want to add a letter (any letter, lets say p) to the end of every word using regular javascript but im not sure how to do this.
I already have this incomplete code.
var y = prompt("type a sentence here!"); //person types in sentence that will get changed//
function funkyfunction() {
for(var i=0;i<x.length;i++){
if(x.charAt(i)==" "){
}
}
};
funkyfunction(); //would call the function and print the result
You could use split, which will split a string on each occurrence of the character you provide it and return an array.
So "Type a sentence here".split(" ") would return ["Type", "a", "sentence", "here"].
You could then iterate over that array and add a character to the end of each element!
Then use join to convert the array back into a string. Make sure you pass join the right separator!
Building on the last answer the specifics on how to join them together would be something like this
var x = prompt("type a sentence here!"); //person types in sentence that will get changed//
function funkyfunction()
{
var words = x.split(" ");
for (var i = 0; i < words.length; i++) {
words[i] += "p";
}
x = words.join(" ");
console.log(x); // or alert(x); which ever is most useful
}
funkyfunction(); //would call the function and print the result
As you can see we split the string into an array by the delimiter of space to get an array of words, then we loop through the items in the array and just add p to the end of it. at the end we set the original variable equal to the array combined back together with the spaces added back.

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().

split string into array of n words per index

I have a string that I'd like to split in an array that has (for example) 3 words per index.
What I'd also like it to do is if it encounters a new line character in that string that it will "skip" the 3 words limit and put that in a new index and start adding words in that new index until it reaches 3 again. example
var text = "this is some text that I'm typing here \n yes I really am"
var array = text.split(magic)
array == ["this is some", "text that I'm", "typing here", "yes I really", "am"]
I've tried looking into regular expressions, but so far I can't really make sense of the syntax that is used in regex.
I have written a way to complicated function that splits my string into lines of 3 by first splitting it into an array of separate words using .split(" "); and then using a loop to add add it per 3 into another array. But with that I can't take the new line character into account.
You can try with this pattern:
var result = text.match(/\b[\w']+(?:[^\w\n]+[\w']+){0,2}\b/g);
since the quantifier {0,2} is greedy by default, it will take a value less than 2 (N-1) only if a newline is found (since newlines are not allowed here: [^\w\n]+) or if you are a the end of the string.
If you're interested in a regexp solution, it goes like this:
text.match(/(\S+ \S+ \S+)|(\S+ \S+)(?= *\n|$)|\S+/g)
// result ["this is some", "text that I'm", "typing here", "yes I really", "am"]
Explanation: match either three space separated words, or two words followed by spaces + newline, or just one word (a "word" being simply a sequence of non-spaces).
For any number of words, try this:
text.match(/((\S+ ){N-1}\S+)|(\S+( \S+)*)(?= *\n|$)|\S+/g)
(replace N-1 with a number).
Try something like this:
words = "this is some text that I'm typing here \n yes I really am".split(" ");
result = [];
temp = "";
for (i = 0; i < words.length; i++) {
if ((i + 1) % 3 == 0) {
result.push(temp + words[i] + " ");
temp = "";
} else if (i == words.length - 1) {
result.push(temp + words[i]);
} else {
temp += words[i] + " ";
}
}
console.log(result);
Basically what this does is splits the string by words, then loops through each word. Every third word it gets to, it adds that along with what is stored in temp into the array, otherwise it adds the word to temp.
Only if you know there are no words 'left', so the number of words is always a multiple of 3:
"this is some text that I'm typing here \n yes I really am".match(/\S+\s+\S+\s+\S+/g)
=> ["this is some", "text that I'm", "typing here \n yes", "I really am"]
but if you add a word:
"this is some text that I'm typing here \n yes I really am FOO".match(/\S+\s+\S+\s+\S+/g)
the result will be exactly the same, so "FOO" is missing.
here one more way:
use this pattern ((?:(?:\S+\s){3})|(?:.+)(?=\n|$))
Demo

Categories