I am working on a problem where I need to be able to reverse a sentence but only words that are greater than 4 can be reversed. the rest of the words must be the same as they are. I have tried to check to see if length is greater than 4 but that does not return the result I am looking for. All I need is to reverse any words that are greater than 4 in the sentence. Any help is greatly appreciated.
Edit: Here is the simple of what I know how to do. It reverses all of the sentence. I am sure that there needs to be some way to break apart each word and determine the length of the word and then bring the sentence back together, but I don't know how that would be done.
var sentence = "This could be the answer I need";
if (sentence.length > 4) {
console.log( sentence.split('').reverse().join(''));
}
Thank you
In Short:
var s = 'This is a short sentence'
, e = s.split(' ').map(function(v){ return v.length>4?v.split('').reverse().join(''):v; }).join(' ');
console.log(e); // 'This is a trohs ecnetnes'
Explained:
var s = 'This is a short sentence' // set test sentence
, e = s.split(' ') // 'This is a short sentence' ==> ['This','is','a','short','sentence']
.map(function(v,i,a){ // REPLACE the value of the current index in the array (run for each element in the array)
return v.length > 4 // IF the length of the a 'word' in the array is greater than 4
? v.split('') // THEN return: 'word' ==> ['w','o','r','d']
.reverse() // ['w','o','r','d'] ==> ['d','r','o','w']
.join('') // ['d','r','o','w'] ==> 'drow'
: v; // OR return: the original 'word'
}).join(' '); // ['This','is','a','trohs','ecnetnes'] ==> 'This is a trohs ecnetnes'
console.log(e); // 'This is a trohs ecnetnes'
You've not shown us your source code, so its hard to know how far you got. Not wanting to just give you the code, therefore removing the opportunity to learn how to put it together, I suggest that you look into the following things:
The String split() method, which could be used to split your sentence into individual words in an array
Look into how to iterate over an array of your string words in a for-loop, looking for those that are greater than 4 characters long.
Understand how to reverse a string in situ - see this answer. Only apply this to the strings that are over the right size. Make sure you replace your original strings with the reversed ones in the arry.
Then understand how the Array join() method works.
I'm sorry if I've been over-simplistic in my descriptions - but it is hard to understand from your question how much you need this spelled out. Hope this is helpful.
The simplest approach is to do the following:
Split the string on the space. (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split)
The use the forEach function to loop through each element, reversing if the length is > 4 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
Then finish with join to put all the elements of the array into a string (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join)
// For word length greater than equal to 5
function reverseString(s){
return s.split(' ').
map( v => {
return v.length > 4 ? v.split('').
reverse().join('') : v;
} ).join(' ');
}
OR
function reverseString(string){
return string.replace(/\w{5,}/g, function(w) { return w.split('').reverse().join('') })
}
Replace with your string word length
Use regex to match words with at least 5 characters, and replace with reversed characters:
var s = "I am working on a problem where I need to be able to reverse a sentence but only words that are greater than 4 can be reversed.";
s2 = s.replace(/\b(\w\w\w\w\w+)\b/g, function(word) {
return word.split("").reverse().join("");
});
console.log(s2);
outputs:
I am gnikrow on a melborp erehw I need to be able to esrever a ecnetnes but only sdrow that are retaerg than 4 can be desrever.
fiddle
Related
I'm fairly new to JavaScript (and development in general). I wanted to try a challenge from Codewars. The challenge was to process a string through a function that would flip any words that were over 5 characters and return the original string with those flipped words. Here's the code I came up with (It did work!).
//this function turns each word into an array that will get flipped.
let wordFlipper = (word) => {
var splitWord = word.split(''); //convert word to array
var reversedWord = splitWord.reverse(); //flips the indexes for the array
var joinReversedWord = reversedWord.join('').toString(); //turns array back to a string.
return joinReversedWord;
}
function spinWords(phrase){
let finalArray = [];
let wordsToArray = phrase.split(' ');
const processFlipWords = wordsToArray.forEach(word => {
if (word.toString().length > 4) {
var flippedWord = wordFlipper(word); //here's where we call the function wordFlipper()
finalArray.push(flippedWord);
}
else {
finalArray.push(word);
}
});
return finalArray.join(' ');
}
How would you experts suggest writing this? I'm sure I'm not being too efficient at writing this code.
Thank you!
Here's what it looks like inside codewars!
I'd use a regular expression to match 5 or more word characters (\w{5,}), and have a replacer function (String.replace()) return the reversed (reverse()) word:
const spinWords = phrase => phrase.replace(
/\w{5,}/g,
word => [...word].reverse().join('')
);
console.log(spinWords('foo barbar more words go here'));
\w matches a word character - something from A to Z, case-insensitive, or a digit, or an underscore.
The brackets indicates the number of times to repeat the previous token. {5,} starts with a 5 (so, "at least 5") and has nothing after the comma ("up to any number").
Then /g, the global flag, matches and replaces every substring that matches this pattern, not just the first.
The callback function runs for every matched substring, where the argument is the matched substring, and what is returned gets replaced at that point in the original string.
I've just started coding..I'm a super beginner and have no idea about regex yet so for now I'd rather not use it. This is an exercise I'm trying to solve. The problem is that when a word contains matching characters, the first character gets the lower case, but what I actually want is the last character of the word to become small.
I don't really require a solution for the problem. Instead I'd rather have some insight on what I'm doing wrong and maybe direct me to the right path :)
function alienLanguage(str) {
let bigWords = str.toUpperCase().split(" ");
let lastLetterSmall = [];
bigWords.forEach(words => {
lastLetterSmall
.push(words
.replace(words
.charAt(words.length -1), words.charAt(words.length -1).toLowerCase()));
});
console.log(lastLetterSmall.join(' '));
}
alienLanguage("My name is John");
alienLanguage("this is an example");
alienLanguage("Hello World");
alienLanguage("HELLO WORLD");
Since you only really want to work with indicies of the string - you don't need to replace anything dynamically other than the last index - replace won't work well, since if you pass it a string, it will only replace the first matching letter. For example:
'foo'.replace('o', 'x')
results in 'fxo', because the first o (and only the first o) gets replaced.
For your code, instead of replace, just concatenate the two parts of the string together: the part from index 0 to next-to-last index, and the character at the last index with toLowerCase() called on it:
function alienLanguage(str) {
const result = str
.toUpperCase()
.split(" ")
.map(line => line.slice(0, line.length - 1) + line[line.length - 1].toLowerCase())
.join(' ');
console.log(result);
}
alienLanguage("My name is John");
alienLanguage("this is an example");
alienLanguage("Hello World");
alienLanguage("HELLO WORLD");
I'm working on a lab assignment for a web applications class and am stuck on implementing a word counter for a basic HTML webpage. The setup of the tests and HTML are already done for us. I simply need to write a function called countWords that takes a string and returns the number of words. It works differently from your traditional word counter though. A word is defined as anything A-Z. Everything else is considered not part of a word. So, if the string is just "234##$^" then the word count is 0. So, I'm not just counting white space like most word counters. All the answers I've found on StackOverflow to similar questions try to just count white space and don't work for my situation. Hence why I made a new question.
My idea was to have a return statement that matches any grouping of a-z using a regular expression and return the length. Then, have a conditional to check for the empty string or string with no letters a-z.
function countWords(s) {
if(s === "" || s === "%$#^23#") {
return 0
}
return s.match(/[^a-z]/gi).length
}
Right now the if statement is just matching the two test cases so that I can pass my tests. I'm not sure how to go about writing another match regular expression to check for no letters in the string or the empty string. Any help is appreciated! Been stuck for a while.
const str1 = '%$#^23#';
const str2 = 'String with ___ special characters and #$&# white spaces !!!';
const str3 = 'Special &$%# characters --> and %$#^5# connected,words but our <++##||++> function,still_works!';
const wordCount = (str) => str.replace(/[\W_\d]/g,' ').split(' ').filter(Boolean).length;
console.log(wordCount(str1)); // 0
console.log(wordCount(str2)); // 7
console.log(wordCount(str3)); // 11
use "regex" to replace all special characters, underscores, numbers, and extra white spaces with an empty space
--> replace(/[\W_\d]/g,' ')
convert the string into an array
--> .split(' ')
use filter to remove all empty string(s) in the array
--> .filter(Boolean)
then, get the word count with "length"
--> .length
You first need to filter the string, remove all the special characters and numbers:
var filtered_test = my_text.replace(/[^a-zA-Z ]/g, '');
then do a normal split and count:
var words = filtered_test.split(" ");
console.log(words.length); //prints out the count of words
You can use a functional replace method to chunk all of the "words" into an array, then simply return the array length. This has the added benefit of providing a 0 count:
explanatory version:
function countWords(str, words = []) {
str.replace(/[A-Z]+/gi, (m) => words.push(m));
return words.length;
}
minimal version:
let countWords = (str, words = []) =>
( str.replace(/[A-Z]+/gi, (m) => words.push(m)), words.length );
let countWords = (str, words = []) => (str.replace(/[A-Z]+/gi, (m) => words.push(m)), words.length);
console.log( "##asdfadf###asfadf: " + countWords("##asdfadf###asfadf") )
console.log("##13424#$#$#$%: " + countWords("##13424#$#$#$%"));
How about this regular expression: /.*?[a-z]+.*?(\s|$)/gi
Use return s.match(/.*?[a-z]+.*?(\s|$)/gi).length
Anything with at least 1 letter in it is counted. Then the phrase O##ne two $#!+ ##%Three four^&&$ five would count as 5 words.
Edit: If you want to be evil to pass your test cases when there are 0 matches use (input.match(/.*?[a-z]+.*?(\s|$)/gi) || "").length
I have this problem im trying to solve but i'm having a hard time getting the output I want. This is what I have.
var stringLength = [];
function wordCount(text) {
stringLength.push(text.split(' ').join(' , '))
console.log(stringLength.length)
}
wordCount('All work and no play makes Jack a dull boy');
This should return '10'. Can anyone let me know where I am going wrong?
You're splitting it up, but then you're joining them all back together....so text.split(' ') forms an array on individual words, but then the .join(' , ') joins all the words together into a single string (separated by commas)
It should just be:
function wordCount(text) {
return text.split(' ').length
}
You just need to split on the spaces (' '), that will return an array of words that you can get the length property from:
function wordCount(text) {
return text.split(' ').length;
}
var count = wordCount('All work and no play makes Jack a dull boy'); //10
console.log(count);
I only want to remove the first 100 words and keep whats remaining from the string.
The code I have below does the exact opposite:
var short_description = description.split(' ').slice(0,100).join(' ');
Remove the first argument:
var short_description = description.split(' ').slice(100).join(' ');
Using slice(x, y) will give you elements from x to y, but using slice(x) will give you elements from x to the end of the array. (note: this will return the empty string if the description has less than 100 words.)
Here is some documentation.
You could also use a regex:
var short_description = description.replace(/^([^ ]+ ){100}/, '');
Here is an explanation of the regex:
^ beginning of string
( start a group
[^ ] any character that is not a space
+ one or more times
then a space
) end the group. now the group contains a word and a space.
{100} 100 times
Then replace those 100 words with nothing. (note: if the description is less than 100 words, this regex will just return the description unchanged.)
//hii i am getting result using this function
var inputString = "This is file placed on Desktop"
inputString = removeNWords(inputString, 2)
console.log(inputString);
function removeNWords(input,n) {
var newString = input.replace(/\s+/g,' ').trim();
var x = newString.split(" ")
return x.slice(n,x.length).join(" ")
}
The reason this is doing the opposite, is that slice returns the selected elements (in this case, the first one hundred) and returns them in it's own array. To get all of the elements after one hundred, you would have to do something like description.slice(100) to get the split array properly, and then your own join to merge back the array.
var short_description = description.split(' ').slice(100).join(' ');