How do I rewrite this as a function? - javascript

as part of a javascript course I've written a simple Caesar cypher script. I want to phrase it as a function but don't quite understand the syntax of functions.#
enter image description here
var userinput = prompt("What's your message?"); //get user input
let alphabet = "abcdefghijklmnopqrstuvwxyz"; //define alphabet
let alphabetupper = alphabet.toUpperCase(); //define alphabet uppercase (else it gets messy to do the lookup!)
let shift=15; //define letter shift
//___________________________________________
let result = "";
for (let i = 0; i < userinput.length; i++) {
let letter = userinput[i]; //declare letter as userinput char at index
if (letter.toLowerCase()==letter.toUpperCase()){ //if its not a letter...
result +=letter; //print it to result
}
else if ((letter===letter.toUpperCase())) { //else if it is an uppercase letter...
let j=alphabetupper.indexOf(letter); //get index of letter in alphabet "j"
if ((j+shift)<25){ //check shift pos is less than end of alphabet
result+= ((alphabetupper[j+shift])); //print uppercase letter 15 places forward of result
}
else if ((j+shift)>25){ //if the new index is past z...
result+=((alphabetupper[j+(shift-26)])); //loop past z
}
}
else if (/*(letter.toLowerCase()!==letter.toUpperCase())&&*/(letter==letter.toLowerCase())) { //if it is a lowercase letter...
let j=alphabet.indexOf(letter); //get index of letter in alphabet "j"
if ((j+shift)<25){ //check shift pos is less than end of alphabet
result+= (alphabet[j+shift]); //print letter 15 places forward to result
}
else if ((j+shift)>25){ //if the new index is past z...
result+=(alphabet[j+(shift-26)]); //loop past z
}
}
};
alert(("Your encoded message is ") + (result)); //Output result

All you have to do now is run the code i called the function in the last line
function ceasar (userinput){
var userinput = prompt("What's your message?"); //get user input
let alphabet = "abcdefghijklmnopqrstuvwxyz"; //define alphabet
let alphabetupper = alphabet.toUpperCase(); //define alphabet uppercase (else it gets messy to do the lookup!)
let shift=15; //define letter shift
//___________________________________________
let result = "";
for (let i = 0; i < userinput.length; i++) {
let letter = userinput[i]; //declare letter as userinput char at index
if (letter.toLowerCase()==letter.toUpperCase()){ //if its not a letter...
result +=letter; //print it to result
}
else if ((letter===letter.toUpperCase())) { //else if it is an uppercase letter...
let j=alphabetupper.indexOf(letter); //get index of letter in alphabet "j"
if ((j+shift)<25){ //check shift pos is less than end of alphabet
result+= ((alphabetupper[j+shift])); //print uppercase letter 15 places forward of result
}
else if ((j+shift)>25){ //if the new index is past z...
result+=((alphabetupper[j+(shift-26)])); //loop past z
}
}
else if (/*(letter.toLowerCase()!==letter.toUpperCase())&&*/(letter==letter.toLowerCase())) { //if it is a lowercase letter...
let j=alphabet.indexOf(letter); //get index of letter in alphabet "j"
if ((j+shift)<25){ //check shift pos is less than end of alphabet
result+= (alphabet[j+shift]); //print letter 15 places forward to result
}
else if ((j+shift)>25){ //if the new index is past z...
result+=(alphabet[j+(shift-26)]); //loop past z
}
}
};
alert(("Your encoded message is ") + (result)); //Output result
}
ceasar();

Put a function foo() { before your code and an } after it, and you've created a function with the name foo and no arguments.
When you now call the function by invoking it
foo();
you will execute the code between the curly braces {...}
Since ES6+ you can define the function as a const lambda (also code arrow function). like so:
const foo = () => { /* all your code */ }
You just have to define the function before using it, the approach above allows it to use the function before it appears in the source code.

Related

Function to capitalize first and last letter of each word not working

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

Get duplicate character in javascript

How to get duplicate character in JavaScript,
As like input:
aaabcccdeffa
Output:
a4bc3def2
Try this:
var str = "aaabcccdeffa"; // Original string
// We are going to create a key-value array to store the number of occurance
// per letter (eg. 'a' : 4, 'b' : 1 etc.)
var store = {};
// Next we loop through each letter in the string
for (var a in str) {
if (store[str[a]] == undefined) { // If this letter has not ben found before, we set the count to 1 (first occurance)
store[str[a]] = 1;
}
else { // else if the letter has been found, we increase the count by one
store[str[a]] += 1;
}
}
// At this point, we have a key value array that contains the count of each letter
// Next, we loop through this array to generate the new string
var newStr = ''; // Initialise new string
for (var char in store) {
newStr += char; // append the letter to the string
if (store[char] > 1) {
newStr += store[char]; // If the count is more than one, we want to show the number too, so we append the number to the string
}
}
Output will be in newStr
you can use a HashTable, which in javascript is done through an Object. This code works
function duplicateCharacters(str) {
//Create an empty object
var hashTable = {};
for(var i = 0; i < str.length; i++){
//Check if the character has already been registered
//If false, register it and link a 1 to it
//If true, increment the integer linked to it
if (hashTable.hasOwnProperty(str[i]))
hashTable[str[i].toString()]++;
else
hashTable[str[i].toString()] = 1;
}
var output = "";
//Go through the hashTable
for(var key in hashTable) {
//Concatenate the key
output += key.toString();
//If the character only appeared once, do not add it
if(hashTable[key] != 1)
output += hashTable[key].toString()
}
return output;
}
Here is the reference code which uses both jquery and Regular expression for calculating the frequency of the character.
// Variable Declaration with Source text
var sourceText="aaabcccdeffa";
var resultText="";
// Splitting the source text to array
var sourceTextArray=sourceText.split("");
var uniqueText = [];
//Fetches Unique text from sourceTextArray in order
$.each(sourceTextArray, function(i, el){
if($.inArray(el, uniqueText) === -1) uniqueText.push(el);
});
//Iteration with unique text array
$.each(uniqueText, function(i, el){
//Regular Expression approach to calculate frequency of character with source text
resultText+=(sourceText.match(new RegExp(el, "g")) || []).length>1?el+(sourceText.match(new RegExp(el, "g")) || []).length:el;
});
alert(resultText);
Working Example Here

How to set an alert if something is not in an array once

Hello I am trying to figure out how to set an alert("not a option") only once per onkeyup if the letter pressed is not in a a-z array.
When a correct onkeyup is pressed, then it runs through the array and removes it.
But I can't put it at the end of the function because it will pop up regardless...
And I can't put it in the loop because it will run multiple times.
//function that compares the letter inputted to the splitWord array
function checkLetter (letter) {
//setting to false first to cover any input
var letterGiven = false;
//run a loop and compare the letter and splitword
for (i = 0; i < numberEmptySpaces; i++) {
if (splitWord[i] === letter) {
letterGiven = true;
//if it is true then letter will equal emptydisplay and replace the "_"
emptyDisplay[i] = letter;
//this updates the emptyDisplay with the letter that was given.
$('#randomId').html(emptyDisplay.join(" "));
}
}
//if it is not true then you lose one live and the letter is unputted to userGuess array
if (!letterGiven) {
livesRemaining--;
userGuesses.push(letter);
$('#wrongWordId').html("[ " + userGuesses.join(", ") + " ]");
$('#livesId').html(livesRemaining);
}
console.log(userGuesses);
console.log(livesRemaining);
//checking to see if the empty display is undated when onkeyup is actived
console.log(emptyDisplay);
}
(This is for a hangman game, it works, just trying to spice it up)
//function that will only allow a-z and space bar to be pressed
function availableLetters(letter) {
var letterGiven = false;
var alphabet = 'abc defghijklmnopqrstuvwxyz'.split('');
//check to see if it splits when called, it does
for (i = 0; i < alphabet.length; i++) {
if (alphabet[i] === letter) {
letterGiven = true;
//removes the current letter from the alphabet array
alphabet.splice(i, 1);
}
}
}
//---------------------------------------------------------------
//starts the initial game
startUp();
//listens for an event, which is onkeyup
$(document).on("keyup", function(event) {
//creates a variable and converts into a string
//fromcharcode is a converts assigned number to a letter and event.which is the number
//toLowerCase just lower cases any string inputed
var keyLetter = String.fromCharCode(event.which).toLowerCase();
availableLetters(keyLetter);
checkLetter(keyLetter);
updateInfo();
You should use indexOf and according to that handle. And check the userGuesses array if don't want to show the alert again.
//function that compares the letter inputted to the splitWord array
function checkLetter (letter) {
//setting to false first to cover any input
var letterGiven = false;
//run a loop and compare the letter and splitword
if(splitWord.indexOf(letter)>=0){
letterGiven = true;
//if it is true then letter will equal emptydisplay and replace the "_"
emptyDisplay[i] = letter;
//this updates the emptyDisplay with the letter that was given.
$('#randomId').html(emptyDisplay.join(" "));
}
//if it is not true then you lose one live and the letter is unputted to userGuess array
if (!letterGiven && userGuesses.indexOf(letter)<0) {
livesRemaining--;
userGuesses.push(letter);
$('#wrongWordId').html("[ " + userGuesses.join(", ") + " ]");
$('#livesId').html(livesRemaining);
}
console.log(userGuesses);
console.log(livesRemaining);
//checking to see if the empty display is undated when onkeyup is actived
console.log(emptyDisplay);
}

For loop in js with function for starter

I have a job. Unfortunately I got stuck. Could you help me.
Project:
Ask a sentence of user analysis.
Ask to see which letters you want the user to count the block.
Count the number of times that the letter occurs in the sentence.
A pop-up window and then type the following sentence: "The letter X times Y occurs in this sentence."
Must be use function!
I write this:
function bernardTheLetterCounter() {
var sentence = prompt("Please type in the phrase to be examined");
var letter = prompt("Please enter the letters were looking for.");
for (i = 0; i <= sentence.length; i++) {
if (sentence.charAt(i) == letter) {
alert("The letter " + letter + " occurs " + sentence.charAt(i) + " times in this sentence.")
}
}
return;
}
bernardTheLetterCounter();
You have to finish the counting (the inside of the loop) then print the result after the loop is done. Like this:
function bernardTheLetterCounter() {
var sentence = prompt("Please type in the phrase to be examined");
var letter = prompt("Please enter the letters were looking for.");
var count = 0; // the counter (initialized to 0)
// use var i instead of i (to make i local not global: this is just an advice)
for (var i = 0; i <= sentence.length; i++) {
if (sentence.charAt(i) == letter) { // if it is THE LETTER
count++; // increment the counter (add 1 to counter)
}
}
alert("The letter " + letter + " occurs " + count + " times in this sentence."); // use counter to print the result after the counting is done
// the return here has no meaning
}
bernardTheLetterCounter();
What you was doing is printing a message every time the letter is found (which is ugly for the user, especially if the count of that letter is big).
The function in this example can be re-used and tested. (ps. the for-loop is not a functional way of solving your problem).
var sentence = prompt("Please type in the phrase to be examined:");
var letter = prompt("Please enter the letter you are looking for:");
function countLettersInString(source, letterToFind) {
return source
.split('')
.filter(function(letter) { return letter === letterToFind; })
.length;
}
console.log([
'letter', letter,
'was found', countLettersInString(sentence, letter),
'times.'
].join(' '));

Would someone explain this code that counts characters?

I have been trying to solve a puzzle of counting characters in a string and found the following code. The code works, but I'm not able to understand the replace part:
function getCharCounts(s) {
var letters = {};
s.replace(/\S/g, function(s){
letters[s] = (isNaN(letters[s] ? 1 : letters[s]) + 1);
});
return letters;
}
console.log(getCharCounts('he111 144pressions'));​
Would someone please explain the code to me or write a simpler version?
function getCharCounts(s) {
// This variable will be visible from inner function.
var letters = {};
// For every character that is not a whitespace ('\S')
// call function with this character as a parameter.
s.replace(/\S/g, function(s){
// Store the count of letter 's' in 'letters' map.
// On example when s = 'C':
// 1. isNaN checks if letters[c] is defined.
// It'll be defined if this is not a first occurrence of this letter.
// 2a. If it's not the first occurrence, add 1 to the counter.
// 2b. If it's the first occurrence, assigns 1 as a value.
letters[s] = (isNaN(letters[s]) ? 1 : letters[s] + 1);
});
return letters;
}
Note: Brackets in isNaN() were wrong. Code above is corrected.
Here's a simpler example:
function getCharCounts(s) {
var letters = {};
var is_not_whitespace = /\S/;
// Iterate through all the letters in the string
for (var i = 0; i < s.length; i++) {
// If the character is not whitespace
if (is_not_whitespace.test(s[i])) {
// If we have seen this letter before
if (s[i] in letters) {
// Increment the count of how many of this letter we have seen
letters[s[i]]++;
} else {
// Otherwise, set the count to 1
letters[s[i]] = 1;
}
}
}
// Return our stored counts
return letters;
}

Categories