function pigIt(str){
let latin = str.split(' ').map(x => x.slice(0,1) + 'ay')
let latinTwo = str.split(' ').map(x => x.slice(1, str.length-1))
for (let i = 0; i < latin.length; i++) {
let pig = latinTwo[i].concat(latin[i])
console.log(pig)
}
}
Testcase:
Test.assertEquals(pigIt('Pig latin is cool'),'igPay atinlay siay oolcay')
My current array of pig contains =
igPay
atinlay
siay
oolcay
I am wondering how I can join this into a full sentence, I've tried using the join method... Any help is much appreciated!
I've tried using the join method however I get an error code.
A simpler approach:
function pigIt(s) {
return s.split(' ').map(i=>i.substring(1)+i.charAt(0)+'ay').join(' ')
}
console.log(pigIt('Pig latin is cool'))
you can also do:
function pigIt(s) {
return s.split(' ').map(([a,...b])=>[...b,a,'ay'].join('')).join(' ')
}
console.log(pigIt('Pig latin is cool'))
You are in right direction, You just have to assign the concatenated string into a variable instead of reassigning it to a whole variable again.
Note : .join method is helpful for arrays, for strings .concat is the method to join.
Live Demo :
function pigIt(str) {
let pig = ''
let latin = str.split(' ').map(x => x.slice(0,1) + 'ay')
let latinTwo = str.split(' ').map(x => x.slice(1, str.length-1))
for (let i = 0; i < latin.length; i++) {
pig += latinTwo[i].concat(latin[i], " ")
}
return pig;
}
console.log(pigIt('Pig latin is cool').trim());
Related
I am currently learning TypeScript and I am trying to create a function that accepts a string parameter and reverses each word in the string.
Here is what I am looking for in my return:
"This is an example!" ==> "sihT si na !elpmaxe"
This is a solution I created. I am trying to avoid built-in methods.
export function reverseWords(str: string): string {
var newStr = "";
str.split("");
for(var i = str.length -1; i >= 0; i--){
newStr += str[i];
}
return newStr;
}
reverseWords("Hi. How are you?")
This code gives me the following:
"This is an example!" ==> !elpmaxe na si sihT
I am looking for this:
"This is an example!" ==> "sihT si na !elpmaxe"
Can someone explain to me what it is I am doing wrong?
Your function is good, but it reverse the string it gets, Just add another function which uses your function to reverse just the words:
export function reverseStringWords(str: string): string {
var words = str.split(" ");
var revWords = words.map(function(word){
return reverseWords(word);
});
return revWords.join(" ");
}
You can rename your function to reverseWord so it will make more sense in the context.
You don't want to reverse the whole string, but only each word inside the string, preserving each word's relative position. You could split by spaces first, then reverse each substring:
const reverse = str => str
.split(' ')
.map(word => [...word].reverse().join(''))
.join(' ');
console.log(reverse("This is an example!"));
or if you really want to do it manually, assuming split is allowed:
const reverse = str => {
const words = str.split(' ');
const outWords = [];
for (const word of words) {
let letter = '';
for (let i = word.length - 1; i >= 0; i--) {
letter += word[i];
}
outWords.push(letter);
}
return outWords.join(' ');
};
console.log(reverse("This is an example!"));
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"));
So far I have:
function pigIt(str) {
//split string into array of words
let words = str.split(" ");
//loop through array of words
for (let i = 0; i < words.length; i++) {
//loop through individual words
for (let j = 0; j < words.length; j++) {
//get first word in words
let firstWord = words[0];
//get first character in first word
let firstChar = firstWord[0];
//Create new word without first character
let unshiftedWord = firstWord.unshift(0);
//move first character to the end
let newWord = unshiftedWord.push(firstChar) + "ay";
return newWord;
}
}
}
console.log(pigIt('Pig latin is cool'));
For now, I would just like to return "igPay". Then, I will combine the strings together to form a new string.
But it doesn't like firstWord.unshift(0);. It's saying:
TypeError: firstWord.unshift is not a function.
But .unshift() is a function? Why isn't that working?
Once I can get a new word, I should be able to combine the newWords together into a newString, although there's probably a more efficient way than creating new for-loops for each individual word.
https://www.codewars.com/kata/520b9d2ad5c005041100000f/train/javascript
EDIT: I'm looking to write this function with traditional function declaration, not with arrow notation.
EDIT 2 After implementing #Ori Drori's code, my function looks like:
function pigIt(str) {
newString = str.replace(/(\S)(\S+)/g, '$2$1ay');
return newString;
}
console.log(pigIt('Pig latin is cool'));
And it works - but I don't understand what str.replace(/(\S)(\S+)/g, '$2$1ay'); is doing, exactly.
A simpler way to that is using map() and join().
Note: that according to codewars example only ay is added to string containing aplhabets not !. So you should test whether the the element of array is aplhabet or not using test().
All the tests in the codewars are passed for following solution.
function pigIt(str){
return str.split(' ').map(x =>/[a-zA-Z]+/.test(x) ? x.slice(1)+x[0]+'ay' : x).join(' ');
}
console.log(pigIt('Pig latin is cool'));
Without arrow function.
function pigIt(str){
return str.split(' ').map(function(x){
return /[a-zA-Z]+/.test(x) ? x.slice(1)+x[0]+'ay' : x;
}).join(' ');
}
console.log(pigIt('Pig latin is cool'));
Simple for loop
Here is the code using simple for loop
function pigIt(str){
str = str.split(' ');
for(let i = 0;i<str.length;i++){
if(/[a-zA-Z]/.test(str[i])){
str[i] = str[i].slice(1) + str[i][0] + 'ay';
}
}
return str.join(' ');
}
console.log(pigIt('Pig latin is cool'));
unshift in not an method on string
You can simply split on space and than map and swap places and add ay and join them with space again.
let str = `Pig latin is cool`
let op = str.split(' ').map(e=> e.substr(1,) +e[0] + 'ay').join(' ')
console.log(op)
Without arrow function
let str = `Pig latin is cool`
let op = str.split(' ').map(function(e){
return e.substr(1,) +e[0] + 'ay'
}).join(' ')
console.log(op)
You can use a RegExp (regex101) and String.replace(). The regex catches the head (1st letter) and tail (the other letters) of each word (actually sequence of non space values). Use the replacement ($2$1ay) to rebuild the word in pig latin.
const pigIt = (str) => str.replace(/(\w)(\w+)/g, '$2$1ay')
console.log(pigIt('Pig latin is cool'));
How does the replace work:
The regex collects the 1st word character (\w) and assigns it to $1
The regex collects the rest of the word's characters and assigns them to $2
The replacement defines that the new string would be $2 then $1 and then "ay"
Note: I've used \S to catch all non space characters.
Try this it will work and without Regex
function pigIt(str){
let arr = str.split(" ");
let newArr = [];
for ( let i = 0 ; i < arr.length ; i++ ) {
if ( arr[i] === "!" || arr[i] === "?" ){
newArr.push(arr[i]);
} else {
let s = arr[i].slice(1)+arr[i].charAt(0)+"ay"
newArr.push(s)
}
}
return newArr.join(" ")
}
function titleCase(str) {
var str1 = str.match(/\S+\s*/g);
var str2;
for(var i = 0; i < str1.length; i++){
str2 = str1[i].toLowerCase().replace(str1[i].charAt(0), str1[i].charAt(0).toUpperCase());
}
return str2.join(' ');
}
titleCase("I'm a little tea pot");
What's wrong with my code? str2.join is not a function
Easiest way to go about this is to split the string on every space, then set the first letter of each element in the array to the capitalized version of the letter and join it back.
What you are doing is assigning the value of the result to str2, having a string type rather than an array, that is why join is not working for you.
function titleCase(str) {
const words = str.split(' ');
for (let i = 0; i < words.length; i++) {
words[i] = words[i][0].toUpperCase() + words[i].slice(1);
}
return words.join(' ');
}
A slightly different variant with some ES6 favor to it:
const titleCase = str => {
const result = [];
for (const word of str.split(' ')) {
result.push(word[0].toUpperCase() + word.slice(1));
}
return result.join(' ');
};
If you want to ensure space characters such as tabs, newlines etc. work, you can split using your regex or replace all whitespace characters with spaces as a first step, e.g.:
const words = str.replace(/\s/g, ' ').split(' ').filter(word => word !== '');
function titleCase(str) {
var str1 = str.match(/\S+\s*/g);
var str2 = [];
for(var i = 0; i < str1.length; i++){
str2[i] = str1[i].replace(str1[i].charAt(0), str1[i].charAt(0).toUpperCase());
}
return str2.join(' ');
}
titleCase("I'm a little tea pot");
This is a simple solution to your problem. However, there are many ways to get the same result this is one of them.
function capitalize(str) {
let str2 = str[0].toUpperCase();
return str.replace(str[0], str2);
}
This question already has answers here:
Convert string to Title Case with JavaScript
(68 answers)
Closed 5 years ago.
I've been trying to capitalize the first letter of each word in a string, but it says TypeError: Cannot assign to read only property '0' of string 'i' . My logic looks fine but surely the way I'm doing this is not right. Any suggestions.
function titleCase(str) {
str = str.toLowerCase();
var word = str.split(" ");
// console.log(word[0][0]);
for (var i = 0; i < word.length - 1; i++) {
word[i][0] = word[i][0].toUpperCase();
}
console.log(word);
return word;
}
titleCase("I'm a little tea pot");
Try like so: (see comments in code)
function titleCase(str) {
str=str.toLowerCase();
var word = str.split(" ");
for (var i=0; i < word.length; i++) { // you don't need -1 here as you had
word[i] = word[i].charAt(0).toUpperCase() + word[i].slice(1); // see changes in this line
}
console.log(word);
return word;
}
titleCase("I'm a little tea pot");
Strings have a replace method that accepts a function:
var s = 'foo bar fum i am sparticus 23!!';
console.log(s.replace(/\b\w/g, function(s){return s.toUpperCase()}));
You can directly convert your string into what you want by inbuilt array function.
Using map function you will get it directly no need to run for loop.
("I'm a little tea pot")
.split(" ")
.map(function(d){
return d[0].toUpperCase()+d.substring(1,d.length)
}).join(" ")
You can combine split and map functions to achieve this.
function titleCase(str) {
return str.toLowerCase().split(" ").map(function(word) {
var _word = word.split("");
_word[0] = _word[0].toUpperCase();
return _word.join("");
}).join(" ");
}
console.log(titleCase("I'm a little tea pot"));
You can use map function to create an array of modified words and join to recreate the string
function titleCase(str) {
str = str.toLowerCase();
var word = str.split(" ");
var x = word.map(function(item) {
return item.charAt(0).toUpperCase() + item.substring(1, item.length);
}).join(" ");
return x
}
console.log(titleCase("I'm a little tea pot"));
Using only CSS
#test {
text-transform: capitalize
}
<div id="test"> I'm a little tea pot</div>
With split, array map and reduce:
var str = "I'm a little tea pot";
var res = str.split(" ")
.map(word => word.charAt(0).toUpperCase() + word.substr(1))
.reduce((m, o) => { m = m + " " + o; return m }, "")
console.log(res);
Join can be also used instead of reduce:
var str = "I'm a little tea pot";
var res = str.split(" ")
.map(word => word.charAt(0).toUpperCase() + word.substr(1))
.join(" ");
console.log(res);