`join()` and multidimensional arrays Javascript - javascript

I have this code:
var arr = str.split(' ');
for(var i=0, l=arr.length; i<l; i++) {
arr[i].split('');
arr[i][0].toUpperCase();
almost =arr[i].join('');
}
It returns the error "arr[i].join is not a function". I assume I have something wrong with the data types but I have no idea how to fix it.

Here, I think this is what you're looking for:
var str = 'This is a test string';
var arr = str.split(' ');
for(var i=0, l=arr.length; i<l; i++) {
var word = arr[i].split('');
word[0] = word[0].toUpperCase();
arr[i] = word.join('');
}
console.log(arr.join(' '));
JSFiddle: https://jsfiddle.net/6f9yoqtg/1/

It looks like others have explained why join does not work on a string. However, I noticed that your goal seems to be to uppercase every word in str. You can use the String#replace method for that, taking a function as the section parameter.
var string = 'word word words things amazing icons yup'
console.log(string)
string = string.replace(/(\S)(\S*)/g, function (_, first, rest) {
return first.toUpperCase() + rest
})
console.log(string)

When you use arr[i].split() you are not changing original element in array, so when you use arr[i].join('') you get error because arr[i] is still just a string and you can't use join on string. Instead you need to assign new value to that element so your code should look like this.
var arr = 'lorem ipsum'.split(' ');
for (var i = 0, l = arr.length; i < l; i++) {
arr[i] = arr[i].split('');
arr[i][0] = arr[i][0].toUpperCase();
arr[i] = arr[i].join('');
}
console.log(arr.join(' '))
Or instead you can store that value in variable, change it and then set it to value of current element in loop.
var arr = 'lorem ipsum'.split(' ');
for (var i = 0, l = arr.length; i < l; i++) {
var e = arr[i].split('');
e[0] = e[0].toUpperCase();
arr[i] = e.join('')
}
console.log(arr.join(' '))

With ES6, you could use destructuring ans rest syntax.
var str = 'This is a test string';
str = str.split(' ').map(([first, ...rest]) => [first.toUpperCase(), ...rest].join('')).join(' ');
console.log(str);

There are a few concepts that you need to consider here. if I'm not mistaken you are trying to create a function that will capitalize each first letter in a given string.
Start by simply creating a function that will take any string as a parameter using the variable str and then later manipulate it. Think of the function as a funnel something goes into it and then we have something that will come out the other end as an output. make sure you call the function later.
function capitalize(str) { };
capitalize(every firSt lettEr of the sentence);
Now inside the curly brackets is where the magic happens. we can use the .toLowerCase(), in case we might have capital letters some where along the string, and then use the .split() to split apart the letters at every empty space if there are many words in the string that we are trying to capitalize. Remember that after the split() you will no longer have a string but rather a string inside an array. Note that if you use 2 empty spaces in the split(' '), you will only capitalize the very first letter of the sentence.
function capitalize(str) { str = str.toLowerCase().split(' '); return str;}
//call function
capitalize(every firSt lettEr of the sentence);
//outputs ["every first letter of the sentence"]
then to iterate through each word in the array using a simple for loop like you have that will look like this:
for (var i=0; i<str.length; i++){}
in the curly brackets of the loop you will want to add a statement that will take the first letter of each word capitalize it then add the rest of the letters using splice(). it will go through each word in the array until there are non left, which is why we used the str.length. Lastly you will use the str.join() to put together the all the words in the array, that had a space between them, back into a string. it will look like this:
function titleCase(str) {
str = str.toLowerCase().split(' ');
for (var i = 0; i < str.length; i++) {
str[i] = str[i].charAt(0).toUpperCase() + str[i].slice(1);
}
return str.join(' ');
}
capitalize("every firSt lettEr of the sentence");
//output "Every First Letter Of The Sentence"
I hope that helped. if you need any help with the concepts don't be afraid to ask.

Related

What am I missing regarding the toUpperCase method?

I am trying to make the first letter of each word capitalized via toUpperCase method and the rest of the word is in the lower case via the toLowerCase method. But I am missing something... Why temp value is not matching with result[1][0] even if I am using that method for both?
Note: I know about other ways (map, replace, etc) for my solution, but I want to just use a for-loop with toUpperCase and toLowerCase methods.
function titleCase(str) {
let regex = /[^0-9\s]+/g;
var result = str.match(regex);
let temp = "";
for (let i = 0; i < result.length; i++) {
for (let j = 0; j < result[i].length; j++) {
result[1][0] = result[1][0].toUpperCase();
temp = result[1][0].toUpperCase();
}
}
console.log(temp); // Output is 'A'
console.log(result[1][0]); //Output is 'a'
// Normally 'temp' and 'result[1][0]' should be equal, but one returns a lowercase character and the other an uppercase character.
return str;
}
titleCase("I'm a little tea pot");
Your problem is not with the toUppercase(), it is with the reference.
When referencing result[1][0], why are you including the 0? You already have the second character with result[1]
result[1] === 'a'. No need to include the [0] as well.
Change your code so it looks like this:
function titleCase(str) {
let regex = /[^0-9\s]+/g;
var result = str.match(regex);
let temp = "";
result[1] = result[1].toUpperCase();
temp = result[1].toUpperCase();
console.log(temp); // Output is 'A'
console.log(result[1]); //Output is also 'A'
// both now equals capital A
return str;
}
titleCase("I'm a little tea pot");
EDIT:
Updating the function to uppercase the first letter of the word.
We can use ES6, which would make this really simple:
const capitalize = (string = '') => [...string].map((char, index) => index ? char : char.toUpperCase()).join('')
Use it: capitalize("hello") returns 'Hello'.
First we convert the string to an array, using the spread operator, to get each char individually as a string. Then we map each character to get the index to apply the uppercase to it. Index true means not equal 0, so (!index) is the first character. We then apply the uppercase function to it and then return the string.
If you want a more object oriented approach, we can do something like this:
String.prototype.capitalize = function(allWords) {
return (allWords) ?
this.split(' ').map(word => word.capitalize()).join(' ') :
return this.charAt(0).toUpperCase() + this.slice(1);
}
Use it: "hello, world!".capitalize(); returns "Hello, World"
We break down the phrase to words and then recursive calls until capitalising all words. If allWords is undefined, capitalise only the first word meaning the first character of the whole string.
I was tried to change a specific character in the string but strings are immutable in JS so this does not make sense.

How can I dynamically use string.replace?

wordsArray = ['guy', 'like', 'sweet', 'potatoes']; //so on and so forth
string = "I am a **NOUN** and I **VERB** **ADJECTIVE** **NOUN**.";
DELIMITER = "**";
for (var i = 0; i < wordsArray.length; i++)
{
string.replace(DELIMITER, wordsArray[i]);
}
Hi, this is a simplified version of my code. I'm creating a mad lib, and the length of wordsArray will always be equal to the number of fill in the blanks. The problem with my current code is that in the for loop, it will replace every **. The thing is, I want to replace the entire thing, like **NOUN**, not just **. But since whatever is in between ** ** won't always be the same, string.replace() won't exactly work. Can Anyone suggest me an edit that could replace all the part of speeches but still eventually return string as a, well, block of proper text?
You can do it using string.match by catching all those **<STRINGS>** first:
var wordsArray = ['guy', 'like', 'sweet', 'potatoes'];
var string = "I am a **NOUN** and I **VERB-** **ADJECTIVE** **NOUN**.";
var DELIMITER = "**";
var newString = string; // copy the string
var stringArray = string.match(/(\*\*[A-Za-z-]+\*\*)/g); // array of all **<STRINGS>**
for (var i = 0; i < wordsArray.length; i++) {
newString = newString.replace(stringArray[i], wordsArray[i]);
}
console.log(newString);
You can bind your array to the replacer and call replace on your string once, I think it is much simpler:
"I am a **NOUN** and I **VERB** **ADJECTIVE** **NOUN**.".replace(/(\*\*\w+\*\*)/gi,(function(){
this._currentIndex = this._currentIndex || 0;
return this[this._currentIndex++];
}).bind(['guy', 'like', 'sweet', 'potatoes']));
//"I am a guy and I like sweet potatoes."
Using reduce:
const string = "I am a **NOUN** and I **VERB** **ADJECTIVE** **NOUN**.";
const newString = ['guy', 'like', 'sweet', 'potatoes'].reduce(
(theString, replacement) => theString.replace(/\*{2}\w+\*{2}/, replacement),
string
)

Splitting sentence string into array of words, then array of words into arrays of characters within the array of words

I'm working through a problem on freecodecamp.com, and I want to see whether my code so far is doing what I think it is doing...
function titleCase(str) {
var wordArr = str.split(' '); // now the sentences is an array of words
for (var i = 0; i < wordArr.length; i++) { //looping through the words now...
charArr = wordArr[i].split(''); //charArr is a 2D array of characters within words?
return charArr[1][1];
}
}
titleCase("a little tea pot"); // this should give me 'i', right?
Again, this is just the beginning of the code. My goal is to capitalize the first letter of each word in the parameter of titleCase();. Perhaps I'm not even going about this right at all.
But... is charArr on line 4 a multidimensional array. Did that create [['a'],['l','i','t','t','l','e'],['t','e','a','p','o','t']]?
In addition to ABR answer (I can't comment yet) :
charArr is a one-dimensional array, if you want it to be a 2d array you need to push the result of wordArr[i].split(''); instead of assigning it.
charArr.push(wordArr[i].split(''));
And don't forget to initialize charArr as an empty array
Few issues :
1. Your return statement will stop this after one iteration.
2. If one of the words have fewer then 2 letters (like the first one in your example, which is 'a') - you will get an exception at charArr[1][1].
Other then that, it is mostly ok.
It would probably help you to download a tool like firebug and test your code live...
You can do the following:
function titleCase(str) {
var newString = "";
var wordArr = str.split(' ');
for (var i = 0; i < wordArr.length; i++) { //looping through the words now...
var firstLetter = wordArr[i].slice(0,1); // get the first letter
//capitalize the first letter and attach the rest of the word
newString += firstLetter.toUpperCase() + wordArr[i].substring(1) + " ";
}
return newString;
}
Also you need to remove the return statement in your for loop because the first time the for loop goes over the return statement, it will end the function and you will not be able to loop through all the words
Here you can learn more about string.slice() : http://www.w3schools.com/jsref/jsref_slice_string.asp

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.

Using regular expression to split a string

I have a string which I need to separate correctly:
self.view.frame.size.height = 44
I need to get only view, frame, size, and height. And I need to do it with a regular expression.
So far I've tried a lot of variants, none of them are even close to what I want to get. And my code now looks like this:
var testString = 'self.view.frame.size.height = 44'
var re = new RegExp('\\.(.*)\\.', "g")
var array = re.exec(testString);
console.log('Array length is ' + array.length)
for (var i = 0; i < array.length; i++) {
console.log('<' + array[i] + ">");
}
And it doesn't work at all:
Array length is 2
<.view.frame.size.>
<view.frame.size>
I'm new at Javascript, so maybe I want the impossible, let me know.
Thanks.
In Javascript, executing a regexp with the g modifier doesn't return all the matches at once. You have to execute it repeatedly on the same input string, and each one returns the next match.
You also need to change the regexp so it only returns one word at a time. .* is greedy, so it returns the longest possible match, so it was returning all the words between the first and last .. [^.]* will match a sequence of non-dot characters, so it will just return one word. You can't include the second . in the regexp, because that will interfere with the repetition -- each repetition starts searching after the end of the previous match, and there's no beginning . after the ending . of the word. Also, there's no . after height, so the last word won't match it.
EDIT: I've changed the regexp to use \w* instead of [^.]*, because it was grabbing the whole height = 44 string instead of just height.
var testString = 'self.view.frame.size.height = 44';
var re = /\.(\w*)/g;
var array = [];
var result;
while (result = re.exec(testString)) {
array.push(result[1]);
}
console.log('Array length is ' + array.length)
for (var i = 0; i < array.length; i++) {
console.log('<' + array[i] + ">");
}
If you're sure that your data will be always in the same format you can use this:
function parse (string) {
return string.split(" = ").shift().split(".").splice(1);
}
In your context, split is a MUCH better option:
var str = "self.view.frame.size.height = 44";
var bits1 = str.split(" ")[0];
var bits2 = bits1.split(".");
bits2.shift(); // get rid of the unwanted self
console.log(bits2);

Categories