My splice method don't work here (don't give my code attention just I want to know why this code don't work in my console).
function capSpace(txt) {
// write your code here
wordSplit = txt.split("");
for (let i = 0; i < wordSplit.length; i++) {
if (wordSplit[i].toUpperCase() == wordSplit[i]) {
wordSplit.splice(5, 0, " ")
}
}
return wordSplit
}
console.log(capSpace("fausJkalMalkihkLhb"));
First of all, you need to increment the i for each character that you add to the array.
I assume you're trying to add a space before each capital letter, in which case you need to add it at the i index, not the 5th index.
function capSpace(txt) {
// write your code here
wordSplit = txt.split("");
for (let i = 0; i < wordSplit.length; i++) {
if (wordSplit[i].toUpperCase() == wordSplit[i]) {
wordSplit.splice(i, 0, " ");
i++;
}
}
return wordSplit
}
var result = capSpace("fausJkalMalkihkLhb").join('');
console.log(result);
The splice method is adding an empty space to the wordSplit array in your snippet found here:
wordSplit.splice(5, 0, " ")
This is incrementing the length of wordSplit on each iteration and the condition of the for loop:
i < wordSplit.length
will never be satisfied because the length of wordSplit increases which creates an infinite loop and therefore is never able to return wordSplit and therefore never able to console.log the variable of result because it's stuck in an infinite loop.
Related
I have a problem I'm trying to solve. I am trying to insert a space where ever there is a instance of a capital letter. The problem is that the space is pushed into the correct index but for all other instances where a capital letter appears, it doesn't apply that space. I have researched extensively about the splice methods but could not figure out a solution to my problem. Can someone point me in the right direction.
function solution(string) {
let splitStr = [...string];
for(let i = 0; i < splitStr.length; i++) {
if(!splitStr[i].toUpperCase()) return
if(splitStr[i] === splitStr[i].toUpperCase()) {
let indexOfCapLetter = splitStr.indexOf(splitStr[i].toUpperCase());
splitStr.splice(indexOfCapLetter, 0, ' ' );
return splitStr
}
}
}
First issue is that you're returning the array inside your if statement within the loop. This escapes the function after the first capital letter. But after that there's another issue.
Whenever you add a new element to the array, the characters after it are moved to a higher index.
To counter this you can loop through the array backwards so the affected elements are always ones you've already parsed:
function solution(string) {
let splitStr = [...string];
for(let i = splitStr.length-1; i >=0; i--) {
if(splitStr[i] === splitStr[i].toUpperCase()) {
splitStr.splice(i, 0, ' ' );
}
}
return splitStr.join('');
}
console.log(solution('HelloWorldLongString'))
I am doing an exercise on JS Hero website:
Write a function add that takes a string with a summation task and returns its result as a number. A finite number of natural numbers should be added. The summation task is a string of the form '1+19+...+281'.
Example: add('7+12+100') should return 119.
The code I have written is as follows:
function add (string) {
let partsArray = string.split("+");
let added = parseInt(partsArray[0]);
for (let i=0; i<=partsArray.length; i++) {
added = added + parseInt(partsArray[i]);
}
return added;
}
It returns NaN. Any ideas how to solve this one?
You were going out of bounds on your array. Also you should just initialize the added to 0 as you start looking at the array from index 0. Note I added some console.logs to give you an idea of how you might debug something like this.
function add (string) {
let partsArray = string.split("+");
console.log("parts", partsArray);
let added = 0;
for (let i=0; i<partsArray.length; i++) {
console.log("i",parseInt(partsArray[i]));
added += parseInt(partsArray[i]);
}
return added;
}
If you add the <= back and run the code with the console.logs you will see in console the following. Note with the <= you have 4 indexes rather than the expected 3. This is because the size is 3 but the array is indexed from zero. When you use < you get the expected answer.
You could also use the reduce method:
function add(string) {
return string.split('+').reduce((accumulator, currentValue) => accumulator +
parseInt(currentValue, 10),0)
}
If you still want to start with the first index ..you can do it like below
function add (string) {
let partsArray = string.split("+");
let added = parseInt(partsArray[0]);
for (let i=1; i<partsArray.length; i++) {
added += parseInt(partsArray[i]);
}
return added;
}
function add(input) {
let myinput = input.split("+") //split your value
let sum = 0;
for (let i = 0; i < myinput.length; i++) {
sum = sum + +myinput[i]; //use + for identify the number value
}
return sum;
}
The simplest possible answer is:
function add(str){
return eval(str)
}
I'm trying to write a Javascript function that counts the vowels in a string by calling another function inside that function, but when I test it in the console it returns 0.
Here is my first function that works fine and recognizes if a string is a vowel:
function isVowel(ch){
var pattern = /[aeiouAEIOU]/
return pattern.test(ch);
};
For the second function none of my ideas have worked. Here are a few examples of what I have tried so far:
This one returns me a 0:
function countVowels(str){
var count = 0;
for(var i; i <= str.length; ++i){
if(isVowel(i)){
++count;
}
}
return count;
};
I also tried the above, but removing the .length after str in the for() area.
Another example, but this one gives me an error:
function countVowels(str){
var count = 0
var pattern = /[aeiouAEIOU]/
for(var i = 1; i <= str.length(pattern); ++i){
if(isVowel(i)){
++count;
}
}
return count;
};
I've tried various other functions as well, but for the sake of keeping this post relatively short I won't continue to post them. I'm quite new to Javascript and I'm not sure what I'm doing wrong. Any help would be greatly appreciated!
Try using .match() with the g attribute on your String.
g: global
i: case insensitive
Regexp documentation
function countVowels(ch){
return ch.match(/[aeiouy]/gi).length;
}
var str = "My string";
alert(countVowels(str)); // 2
Although Robiseb answer is the way to go, I want to let you know why you code is not working (I'm referring your first attempt). Basically you made two mistakes in the loop:
As CBroe stated, you are passing i to your isVowel function. i is a integer representing the index of the loop, not the actual character inside the string. To get the character you can do str.substr(i, 1), what means "give me one character from the position i inside the string".
You are not giving a initial value to the i variable. When you create a variable, it is undefined, so you can not increment it.
alert(countVowels("hello"));
function countVowels(str) {
var count = 0;
for (var i = 0; i <= str.length; ++i) {
if (isVowel(str.substr(i, 1))) {
count++;
}
}
return count;
};
function isVowel(ch) {
var pattern = /[aeiouAEIOU]/
return pattern.test(ch);
};
UPDATE: You will see that other answers use other methods to select the character inside the string from the index. You actually have a bunch of different options. Just for reference:
str.slice(i,i+1);
str.substring(i,i+1);
str.substr(i,1));
str.charAt(i);
str[i];
i is the index, not the character. It should be:
if (isVowel(str[i])) {
count++;
}
Also, str.length(pattern) is wrong. length is a property, not a function, so it should just be str.length.
You forgot to assign the value 0 to i variable
And parameter for isVowel is the character, not the index of string
Here information about the JS language: https://stackoverflow.com/tags/javascript/info
function isVowel(ch){
var pattern = /[aeiouAEIOU]/
return pattern.test(ch);
}
function countVowels(str){
var count = 0;
// you forgot to assign the value to i variable
for(var i = 0; i < str.length; i++){
// isVowel(str[i]), not isVowel(i)
if(isVowel(str[i])){
count++;
}
}
return count;
}
console.log(countVowels('forgot'))
Obviously you should do it this way:
function isVowel(c){
var lc = c.toLowerCase();
if(lc === 'y'){
return (Math.floor(Math.random() * 2) == 0);
}
return ['a','e','i','o','u'].indexOf(lc) > -1;
}
function countVowels(s){
var i = 0;
s.split('').each(function(c){
if(isVowel(c)){
i++;
}
});
return i;
}
console.log(countVowels("the quick brown fox jumps over the lazy dog"));
Which, although less efficient and less useful than other answers, at least has the entertaining property of returning a different count 50% of the time, because sometimes Y.
I have some file contents I'd like to pass on to my server using a javascript function. In the file, there are many empty lines, or those which contain useless text. So far I read every line in as a string stored in an array.
How do I then loop through that content skipping multiple lines such as lines 24,25, 36, 42, 125 etc. Can I put these element id's into an array and tell my for loop to run on every element except these?
Thanks
you can't tell your for loop to iterate all, but skip certain elements. it will basically just count in any direction (simplified) until a certain critera has been met.
you can however put an if inside your loop to check for certain conditions, and chose to do nothing, if the condition is met. e.g.:
(pseudo code below, beware of typing errors)
for(var line=0; line < fileContents.length; line++) {
if(isUselessLine(line)) {
continue;
}
// process that line
}
the continue keyword basically tells the for loop to "jump over" the rest of the current iteration and continue with the next value.
The isUselessLine function is something you'll have to implement yourself, in a way, that it returns true, if the line with the given linenumber is useless for you.
You can try this its not much elegent but will suerly do the trick
<html>
<body>
<p>A loop which will skip the step where i = 3,4,6,9.</p>
<p id="demo"></p>
<script>
var text = "";
var num = [3,4,6,9];
var i;
for (i = 0; i < 10; i++) {
var a = num.indexOf(i);
if (a>=0) {
continue;
}
text += "The number is " + i + "<br>";
}
document.getElementById("demo").innerHTML = text;
</script>
</body>
You could use something like this
var i = 0, len = array1.length;
for (; i < len; i++) {
if (i == 24 || i == 25) {
array1.splice(i, 1);
}
}
Or you can have an another array variable which got all the items that need to be removed from array1
Another method:
var lines = fileContents.match(/[^\r\n]+/g).filter(function(str,index,arr){
return !(str=="") && uselessLines.indexOf(index+1)<0;
});
If you have many indices to skip, and this depends on the elements of the array, you could write a function that returns the number of elements to skip over for each index in that array (or returns 1, if no skipping required):
for ( let i = 0;
i < array.length;
i += calcNumberOfIndicesToSkip( array, i )){
// do stuff to the elements that aren't
// automatically skipped
}
function calcNumberOfIndicesToSkip( array, i ){
// logic to determine number of elements to skip
// (this may be irregular)
return numberOfElementsToSkip ;
}
In your case:
// skip the next index (i+1)?
for ( let i=0; i<array.length; i+=skipThisIndex(i+1) ){
// do stuff
}
function skipThisIndex(i){
const indicesToSkip = [ 24, 25, 36, 42, 125 ];
return 1 + indicesToSkip.includes(i);
}
// returns 1 if i is not within indicesToSkip
// (there will be no skipping)
// => (equivalent to i++; normal iteration)
// or returns 1 + true (ie: 2) if i is in indicesToSkip
// => (index will be skipped)
I am trying to get all combination of a number. For example, input "123" should return ["123", "231", "213", "312", "321", "132"].
Here is my function:
function swapDigits(input) {
for (var i = 0; i++; i < input.length - 1) {
var output = [];
var inter = input.slice(i, i + 1);
var left = (input.slice(0, i) + input.slice(i + 1, input)).split("");
for (var j = 0; j++; j <= left.length) {
var result = left.splice(j, 0, inter).join("");
output.push(result);
}
}
console.log(output);
return output;
}
However this function returns undefined, could anyone tell me what's going wrong?
The errors with the for loop and scope have already been mentioned. Besides that, the splice method will change the string that it operates on. This means that the inner loop will never terminate because left keeps on growing, so j never reaches left.length.
If you are new to a language, I would suggest starting with an implementation that is close to the algorithm that you want to implement. Then, once you are comfortable with it, use more advanced language constructs.
See this fiddle for an example. This is the algorithm code:
function getPermutations(input)
{
if(input.length <= 1)
{
return [input];
}
var character = input[0];
var returnArray = [];
var subPermutes = getPermutations(input.slice(1));
debugOutput('Returned array: ' + subPermutes);
for(var subPermuteIndex = 0; subPermuteIndex < subPermutes.length; subPermuteIndex++ )
{
var subPermute = subPermutes[subPermuteIndex];
for(var charIndex = 0; charIndex <= subPermute.length; charIndex++)
{
var pre = subPermute.slice( 0, charIndex );
var post = subPermute.slice( charIndex );
returnArray.push(pre+character+post);
debugOutput(pre + '_' + character + '_' + post );
}
}
return returnArray;
}
Basically, this will walk to the end of the string and work its way back constructing all permutations of sub-strings. It is easiest to see this from the debug output for 1234. Note that 'Returned array' refers to the array that was created by the permutations of the sub-string. Also note that the current character is placed in every position in that array. The current character is shown between _ such as the 1 in 432_1_.
Returned array: 4
_3_4
4_3_
Returned array: 34,43
_2_34
3_2_4
34_2_
_2_43
4_2_3
43_2_
Returned array: 234,324,342,243,423,432
_1_234
2_1_34
23_1_4
234_1_
_1_324
3_1_24
32_1_4
324_1_
_1_342
3_1_42
34_1_2
342_1_
_1_243
2_1_43
24_1_3
243_1_
_1_423
4_1_23
42_1_3
423_1_
_1_432
4_1_32
43_1_2
432_1_
This algorithm doesn't enforce uniqueness. So, if you have a string 22 then you will get two results - 22,22. Also, this algorithm uses recursion which I think is quite intuitive in this case, however there are pure iterative implementations if you look for them.
There are several errors in that code.
You have the order of the parts of the for statement incorrect. The order is initialization, test, increment. So for (/* init */ ; /* test */ ; /* increment */)
You're creating a new array for each iteration of your outer loop.
I'm making this a CW because I haven't checked for further errors than the above.