Why won't this iterate? - javascript

I am trying to make this Pig Latin function (I just started coding 3 weeks ago, so go easy on me), and I can't figure out why I can't get the array made from .split(' ') and then iterated through to join back again. In the output I only get the first word. The code is below:
function pigLatin(str) {
let str1 = str.split(' ')
for (let i = 0; i < str1.length; i++) {
if (str1[i].length <= 1) {
return str1[i];
}
else {
let first = str1[i].substring(0,1);
let word = str1[i].substring(1);
str = word + first + 'ay';
return str
}
}
}
console.log(pigLatin("This is a test"));
Keep in mind that I was considering adding regex and more else if statements, but I can't even get this to work yet. Any help is greatly appreciated.

You're returning too early. You should be adding each word to an array, and at the end of your loop you should concatenate the words in the array to form a new string which you should return. See my comments for how I altered your code:
function pigLatin(str) {
let r = [] // The array to build
let str1 = str.split(' ')
for (let i = 0; i < str1.length; i++) {
if (str1[i].length <= 1) {
r.push( str1[i] ); // Add to end of array
}
else {
let first = str1[i].substring(0,1);
let word = str1[i].substring(1);
str = word + first + 'ay';
r.push(str) // Add to end of array
}
}
return r.join(' ') // Join strings in array and return new string
}
console.log(pigLatin("This is a test"));

Related

Specific Array element replace

I'm solving a simple problem where I need to capitalize the first alphabet of all words. I was able to do that but I have another string vn52tqsd0e4a if any of my output is matched with this string I have to replace it with --[matched string]-- .
so the expected output should be H--e--llo Worl--d--
but when I'm trying to replace the element with -- it's not doing anything. I tried replace() method as well but it didn't work. I don't know what I'm doing wrong here.
function LetterCapitalize(str) {
// code goes here
let array = str.split(" ")
for (let i=0; i<array.length; i++){
array[i] = array[i].charAt(0).toUpperCase() + array[i].slice(1)
}
let output = array.join(" ") ;
let comp = "vn52tqsd0e4a".split("");
for (let i=0; i<output.length; i++){
comp.map(el=> {
if(output[i] === el){
console.log( `matched ${output[i]}` )
output[i] = `--${output[i]}--`;
console.log(output[i]);
}
})
//
}
console.log(output);
}
LetterCapitalize("hello world");
You can achieve this using split, map, join as:
function LetterCapitalize(str) {
// code goes here
let array = str.split(' ');
for (let i = 0; i < array.length; i++) {
array[i] = array[i].charAt(0).toUpperCase() + array[i].slice(1);
}
let output = array.join(' ');
let comp = 'vn52tqsd0e4a'.split('');
const result = output
.split('')
.map((c) => (comp.includes(c) ? `--${c}--` : c))
.join('');
console.log(result);
}
LetterCapitalize('hello world');
You coulduse Array.reduce() to iterate over the str argument and either capitalize or replace depending on the character.
If the preceeding value is a space we'll capitalize, otherwise if the character is in the comp value, we'll replace with --${char}--.
function LetterCapitalize(str) {
const comp = "vn52tqsd0e4a";
return [...str].reduce((acc, char, idx, a) => {
if (idx === 0 || a[idx - 1] === ' ') {
char = char.toUpperCase();
} else if (comp.includes(char)) {
char = `--${char}--`;
}
return acc + char;
}, '')
}
console.log(LetterCapitalize("hello world"));
console.log(LetterCapitalize("hey man"));
What you say to JavaScript in the piece of code is that it should fit 5 characters in a place that can only hold one character.
output[i] = `--${output[i]}--`;
You need to change it to something like this (code below may not work):
output = output.substring(0,i-1) + el + output.substring(i+1,output.length - i-1);
I recommend using the string.replaceAll function instead. If you create a loop yourself you'll get problems when adding more characters on a place where original one character was present.
function LetterCapitalize(str) {
// code goes here
let array = str.split(" ")
for (let i=0; i<array.length; i++){
array[i] = array[i].charAt(0).toUpperCase() + array[i].slice(1)
}
let output = array.join(" ") ;
let comp = "vn52tqsd0e4a".split("");
comp.map(el=> {
output = output.replaceAll(el, '--' + el + '--');
});
console.log(output);
}
LetterCapitalize("hello world");

How to make abbreviations/acronyms in JavaScript?

new to coding I'm trying to make a function that makes "abbreviations/acronyms" of words, e.g. 'I love you' -> 'ily'.
I've tried rewriting the code in many ways but console.log only shows me the first letter of the first given word.
function makeAbbr(words) {
let abbrev = words[0];
let after = 0;
let i = 0;
for (const letter of words) {
if (letter === '') {
i = words.indexOf('', after);
abbrev += words[i + 1];
}
after++;
}
return abbrev;
}
const words = 'a bc def';
let result = makeAbbr(words);
console.log(result)
Without using arrays. But you really should learn about them.
Start by trimming leading and trailing whitespace.
Add the first character to your acronym.
Loop over the rest of the string and add the current character to the acronym if the previous character was a space (and the current character isn't).
function makeAbbr(words) {
words = words.trim();
const length = words.length;
let acronym = words[0];
for(let i = 1; i < length; i++) {
if(words[i - 1] === ' ' && words[i] !== ' ') {
acronym += words[i];
}
}
return acronym;
}
console.log(makeAbbr('I love you'));
console.log(makeAbbr('I love you'));
console.log(makeAbbr(' I love you '));
And here's the version for GottZ
function w(char) {
char = char.toLocaleLowerCase();
const coll = Intl.Collator('en');
const cmpA = coll.compare(char, 'a');
const cmpZ = coll.compare(char, 'z');
return cmpA >= 0 && cmpZ <= 0;
}
function makeAbbr(words) {
words = words.trim();
const length = words.length;
if(!length) return '';
let acronym = words[0];
for(let i = 1; i < length; i++) {
if(!w(words[i - 1]) && w(words[i])) {
acronym += words[i];
}
}
return acronym;
}
console.log(makeAbbr('I love you'));
console.log(makeAbbr('I love you'));
console.log(makeAbbr(' I love you '));
console.log(makeAbbr(' \tI ... ! love \n\r .you '));
console.log(makeAbbr(' \tI ... ! Löve \n\r .ÿou '));
Since you wanted something using your approach, try this (code is commented)
function makeAbbr(words) {
let abbrev = "";
for (let i = 0; i < words.length - 1; i++) { // Loop through every character except the last one
if (i == 0 && words[i] != " ") { // Add the first character
abbrev += words[i];
} else if (words[i] == " " && words[i + 1] != " ") { // If current character is space and next character isn't
abbrev += words[i + 1];
}
}
return abbrev.toLowerCase();
}
const words = 'a bc def';
let result = makeAbbr(words);
console.log(result)
here is my implementation of your function:
Split the sentence into an array, get the first letter of each word and join them into one string.
const makeAbbr = string => string.split(' ').map(word => word[0]).join('');
console.log(makeAbbr('stack overflow'));
console.log(makeAbbr('i love you'));
`
If you want to use your approach exactly, you had a typo on the line specified. A character can never be "" (an empty string), but a character can be a space " ". Fixing this typo makes your solution work.
function makeAbbr(words) {
let abbrev = words[0];
let after = 0;
let i = 0;
for (const letter of words) {
if (letter === ' ') { // This line here
i = words.indexOf(' ', after);
abbrev += words[i + 1];
}
after++;
}
return abbrev.toLowerCase(); // Also added .toLowerCase()
}
const words = 'a bc def';
let result = makeAbbr(words);
console.log(result)
There are couple of things tripping you up.
let abbrev = words[0]; is just taking the first letter of the word string you passed into the function, and at some point adding something new to it.
for (const letter of words) {...}: for/of statements are used for iterating over arrays, not strings.
Here's a remixed version of your code. It still uses for/of but this time we're creating an array of words from the string and iterating over that instead.
function makeAbbr(str) {
// Initialise `abbrev`
let abbrev = '';
// `split` the string into an array of words
// using a space as the delimiter
const words = str.split(' ');
// Now we can use `for/of` to iterate
// over the array of words
for (const word of words) {
// Now concatenate the lowercase first
// letter of each word to `abbrev`
abbrev += word[0].toLowerCase();
}
return abbrev;
}
console.log(makeAbbr('I love you'));
console.log(makeAbbr('One Two Three Four Five'));

For loop if statement stopping on first case

The challenge:
Write a function that takes in a string of one or more words, and returns the same string, but with all five or more letter words reversed (Just like the name of this Kata). Strings passed in will consist of only letters and spaces. Spaces will be included only when more than one word is present.
Example:
spinWords( "Hey fellow warriors" ) => returns "Hey wollef sroirraw"
At the moment I have this
function spinWords(str) {
var splitArray = str.split(' ')
for (var i = 0; i < splitArray.length; i++) {
if (splitArray[i].length > 5) {
var long = splitArray[i].split('').reverse('').join('')
return long
i++
} else {
var short = splitArray[i]
return short
i++
}
}
}
As I said in the title, this is working properly but will only return the first element in the array as reversed or not. Can anyone smarter than me please explain why the loop is not looping?
Thank you for your time.
Return ends the function.
Another approach.
const spinWords = words =>
words
.split(" ")
.map(word => (word.length >= 5 ? [...word].reverse().join("") : word))
.join(" ");
console.log(spinWords("Hey fellow warriors"));
you are almost there..
using for loop, you do not want to do another i++..
you said that it would be 5 or more.. so it should be >=5
return terminates the for loop, so use it last..
the modified function can look like this:
function spinWords(str){
var splitArray = str.split(' ');
var spinnedWords = '';
for (var i = 0; i < splitArray.length; i++) {
if (splitArray[i].length >= 5) {
var long = splitArray[i].split('').reverse('').join('');
spinnedWords = spinnedWords.concat(' ' + long);
}
else {
var short = splitArray[i]
spinnedWords = spinnedWords.concat(' ' + short);
}
}
return spinnedWords.trim();
}
Three things must be changed for this code to work properly.
First
The return statement will finish the entire function execution. So it should be placed at the end of the body when no more code will be executed.
Second
You can switch the values you are iterating over and then return the same array with the inverted operation of the first line (.join(' ')).
Third
The for loop already increment the index counter at the end of each iteration if you defined it in the parameters. You don't need i++ inside the loop body.
function spinWords(str) {
var splitArray = str.split(' ');
for (var i = 0; i < splitArray.length; i++) {
if (splitArray[i].length >= 5) {
var long = splitArray[i]
.split('')
.reverse('')
.join('');
splitArray[i] = long;
}
}
return splitArray.join(' ')
}
EDIT: There's no need for else statement
EDIT2: I forgot the third change needed
function spinWords(str) {
return str
.split(" ")
.map(word => word.length >= 5 ? word.split("").reverse().join("") : word)
.join(" ");
}
console.log( spinWords("Hey fellow warriors") );
This is my answer after your tips:
function spinWords(str){
var splitArray = str.split(' ')
var finalArray = []
for (var i = 0; i < splitArray.length; i++) {
if (splitArray[i].length >= 5) {
var long = splitArray[i].split('').reverse('').join('')
finalArray.push(long)
}
else {
var short = splitArray[i]
finalArray.push(short)
}
}
return finalArray.join(' ')
}

Write a function which takes a sentence as an input and output a sorted sentence

I need to write a function which takes a sentence as an input and output a sorted sentence. and there are two criteria:
Each character of the word should be arranged in alphabetical order
Words should be arranged in ascending order depending on its character count
Note: - Word only can have lowercase letters
Example :
Inputs str = "she lives with him in a small apartment"
Output = "a in ehs him hitw eilsv allms aaemnprtt"
Here is my code.
function makeAlphabetSentenceSort(str) {
var sens = str.split(' ');
sens.sort(function(a, b) {
return a.length - b.length;
console.log(sens);
});
function alphaSort(b) {
var x = b.split("");
console.log(x.sort().join(""));
}
for (var i = 0; i <= sens.length - 1; i++) {
console.log(alphaSort(sens[i]));
}
}
console.log(makeAlphabetSentenceSort("she lives with him in a small enter code hereapartment"));
I'm confused about how to solve that. Any suggestion, please?
It appears that your code mostly works. I was able to get the correct output by replacing console.log(x.sort().join("")); with return x.sort().join("");
I also had to remove console.log(alphaSort(sens[i])); in favor of storing the loop output in a temp variable called output and then returning the entire loop output as a string.
function makeAlphabetSentenceSort(str) {
var sens = str.split(' ');
sens.sort(function(a, b){
return a.length - b.length;
});
function alphaSort(b){
var x = b.split("");
return x.sort().join("");
}
var output = "";
for(var i = 0; i <= sens.length - 1; i++){
output += alphaSort(sens[i]) + " ";
}
return output.trim();
}
console.log(makeAlphabetSentenceSort("she lives with him in a small apartment"));
I would also for readability rewrite the code as follows:
Remove alphaSort as a function as it does not need to be a function in the current context.
use let keyword instead of var keyword to instantiate output variable.
instantiate output variable at the top of the function (because this is how JS really works)
function makeAlphabetSentenceSort(str) {
let output = "";
// Sort the initial sentence by words alphabetically.
var sens = str.split(' ');
sens.sort(function(a, b){
return a.length - b.length;
});
for(var i = 0; i <= sens.length - 1; i++){
// Split each word into single characters. Sort the characters and
// join them back as a single string.
output += sens[i].split("").sort().join("");
// Because we want the response to look like a sentence.
output += " ";
}
return output.trim();
}
console.log(makeAlphabetSentenceSort("she lives with him in a small apartment"));

reverse only certain words in string

I am writing a function to reverse only words in a string that are a certain length, in this case 5 or more. I can make each word reverse if it is that length, but I am having trouble returning the right words back to the string.
function spinWords(string){
let splitString = string.split(" ");
console.log(splitString);
splitString.forEach(function(word) {
if (word.length >= 5) {
console.log(word.split("").reverse().join(""));
return word.split("").reverse().join("");
} else if (word.length < 5) {
console.log(word);
return word;
}
//should something go here?
});
console.log(splitString); //returns same output as when called at top of function
newString = splitString.join(" ");
console.log(newString);
}
spinWords("Jammerson is the best friend ever");
Alternatively, When I save the forEach() function into a new variable, the function is returned as undefined. I'm not sure which piece I am missing. Thanks in advance!
First off, your function needs to return a value. Also, try creating another string that will have the new value:
function spinWords(string){
let newString = ''; // added this here
let splitString = string.split(" ");
splitString.forEach(function(word, index) {
if (word.length >= 5) {
newString += word.split("").reverse().join(""); // added this here
} else if (word.length < 5) {
newString += word; // added this here
}
// add a space between characters, unless its the last char
if(splitString.length > index + 1) {
newString += ' '; // added this here
}
});
return newString;
}
console.log(spinWords("Jammerson is the best friend ever"));
You just need a little fix:
function spinWords(string){
let splitString = string.split(" ");
console.log(splitString);
splitString.forEach(function (word, index, arr) {
if (word.length >= 5) {
console.log(word.split("").reverse().join(""));
arr[index] = word.split("").reverse().join("");
} else if (word.length < 5) {
console.log(word);
arr[index] = word;
}
//should something go here?
});
console.log(splitString); //returns same output as when called at top of function
newString = splitString.join(" ");
console.log(newString);
}
spinWords("Jammerson is the best friend ever");
Instead of only iterating the array with forEach you want to map it to a new array of reversed words:
splitString = splitString.map(function(word) {
then the returned words will be taken. That could be shortened to this oneliner:
const reverseWord = str => str.length >= 5 ? str.split``.reverse().join`` : str;
const spinWords = str => str.split` `.map(reverseWord).join` `;

Categories