I am trying to write a recursive function, but I am completely lost as to how to implement it. I currently have the following:
function change(p){
// code for function
}
var c1 = change(start);
var c2 = change(c1);
var c3 = change(c2);
// etc. etc.
Is there any way to do this with a while loop? For example:
while(currentResultofFunction != goal)
nestedly loop through as before until reaches true
function change(p) {
if (p != 1) { // your condition
change(p);
} else return p;
}
What about:
var val = start;
while(val) //or while val != goal
val = change(val);
What you are doing, is not recursive. You maybe mean iterative.
You can loop through the variables in this way:
var n = 2;
for (var i = 1; i <= n; i++) {
if (i == 1) window['c1'] = change(start);
else window['c' + i] = change(window['c' + (i - 1)]);
}
Related
/Write a function called weave that accepts an input string and number. The function should return the string with every xth character replaced with an 'x'./
function weave(word,numSkip) {
let myString = word.split("");
numSkip -= 1;
for(let i = 0; i < myString.length; i++)
{
numSkip += numSkip;
myString[numSkip] = "x";
}
let newString = myString.join();
console.log(newString);
}
weave("weave",2);
I keep getting an infinite loop. I believe the answer I am looking for is "wxaxe".
Here's another solution, incrementing the for loop by the numToSkip parameter.
function weave(word, numToSkip) {
let letters = word.split("");
for (let i=numToSkip - 1; i < letters.length; i = i + numToSkip) {
letters[i] = "x"
}
return letters.join("");
}
Well you need to test each loop to check if it's a skip or not. Something as simple as the following will do:
function weave(word,numSkip) {
var arr = word.split("");
for(var i = 0; i < arr.length; i++)
{
if((i+1) % numSkip == 0) {
arr[i] = "x";
}
}
return arr.join("");
}
Here is a working example
Alternatively, you could use the map function:
function weave(word, numSkip) {
var arr = word.split("");
arr = arr.map(function(letter, index) {
return (index + 1) % numSkip ? letter : 'x';
});
return arr.join("");
}
Here is a working example
Here is a more re-usable function that allows specifying the character used for substitution:
function weave(input, skip, substitute) {
return input.split("").map(function(letter, index) {
return (index + 1) % skip ? letter : substitute;
}).join("");
}
Called like:
var result = weave('weave', 2, 'x');
Here is a working example
You dont need an array, string concatenation will do it, as well as the modulo operator:
function weave(str,x){
var result = "";
for(var i = 0; i < str.length; i++){
result += (i && (i+1)%x === 0)?"x":str[i];
}
return result;
}
With arrays:
const weave = (str,x) => str.split("").map((c,i)=>(i&&!((i+1)%x))?"x":c).join("");
You're getting your word greater in your loop every time, so your loop is infinite.
Try something like this :
for(let k = 1; k <= myString.length; k++)
{
if(k % numSkip == 0){
myString[k-1]='x';
}
}
Looking at what you have, I believe the reason you are getting an error is because the way you update numSkip, it eventually becomes larger than
myString.length. In my code snippet, I make i increment by numSkip which prevents the loop from ever executing when i is greater than myString.length. Please feel free to ask questions, and I will do my best to clarify!
JSFiddle of my solution (view the developer console to see the output.
function weave(word,numSkip) {
let myString = word.split("");
for(let i = numSkip - 1; i < myString.length; i += numSkip)
{
myString[i] = "x";
}
let newString = myString.join();
console.log(newString);
}
weave("weave",2);
Strings are immutable, you need a new string for the result and concat the actual character or the replacement.
function weave(word, numSkip) {
var i, result = '';
for (i = 0; i < word.length; i++) {
result += (i + 1) % numSkip ? word[i] : 'x';
}
return result;
}
console.log(weave("weave", 2));
console.log(weave("abcd efgh ijkl m", 5));
You can do this with fewer lines of code:
function weave(word, numSkip) {
word = word.split("");
for (i = 0; i < word.length; i++) {
word[i] = ((i + 1) % numSkip == 0) ? "x" : word[i];
}
return word.join("");
}
var result = weave("weave", 2);
console.log(result);
I have some code that compares two strings and returns the one with the lowest value, then compares that value to the letterGrade to see which one is the lowest and then returns the higher of the two. My issue is that I am having issues getting this code to work using javascript.
Javascript code:
var result1 = (finalexam.getletterGrade().compareTo(midexam.getletterGrade()));
var result2 = " ";
if (result1 == 0)
{
result2 = midexam.getletterGrade();
}
else if (result1 < 0)
{
result2 = midexam.getletterGrade();
}
else if (result1 > 0)
{
result2 = finalexam.getletterGrade();
}
var result3 = (letterGrade.compareTo(result2));
if (result3 < 0)
{
result2 = letterGrade;
}
JavaScript int doesn't have a ternary compareTo like Java. You could write one. Something like,
function compare(a, b) {
if (a < b) {
return -1;
} else if (a > b) {
return 1;
}
return 0;
}
Then change your compareTo calls to invoke it. Something like
var result1 = compare(finalexam.getletterGrade(), midexam.getletterGrade());
and
var result3 = compare(letterGrade, result2);
my issue was that our backend code sorted our content using Java's compareTo, because of a misunderstanding I attempted to rewrite compareTo in JavaScript, whereas the fix ended up something completely different, however this may solve your issue
String.prototype.compareTo = function (anotherString) {
var len1 = this.length;
var len2 = anotherString.length;
var n = Math.min(len1,len2); //If the lengths will always be the same skip n to be assigned to len1 only, get rid of len2
var v1 = this;
var v2= new String(anotherString);
// You could instead set these vars i and j to passed in offsets if you want to start sorting from, in which case else case will be possible, or only the first i == j if statement will always be run
var i = 0;
var j = 0;
if (i == j) {
var k = i;
var lim = n + i;
while (k < lim) {
var c1 = v1[k];
var c2 = v2[k];
if (c1 != c2) {
var returnVal = c1.charCodeAt(0) - c2.charCodeAt(0);
if (returnVal > 0)
return 1;
else
return -1
return 0;
}
k++;
}
} else {
while (n-- != 0) {
var c1 = v1[i++];
var c2 = v2[j++];
if (c1 != c2) {
var returnVal = c1.charCodeAt(0) - c2.charCodeAt(0);
if (returnVal > 0)
return 1;
else
return -1
return 0;
}
}
}
return len1 - len2;
//return 0; //if lengths are always the same, comment the above line, uncomment this line
}
Call it like below
var a = "whatever";
var b = "however";
a.compareTo(b);
Hope this helps
I am learning js now..
I am trying to write a simple js programme..
what I am trying to do is to print all valid combinations of n-pair
of parenthesis(properly opened and closed)
eg (), (()()),(())
i have written the logic can you tell me whether its correct or not
https://jsfiddle.net/e7mcp6xb/
module.exports = Parentheses = (function() {
var _isParenthesesMatch = function(str) {
var parentheses = str.length;
var rightParentheses = '(';
var leftParentheses = ')';
var rightCount = 0;
var leftCount = 0;
for(i=0;i<=str.length;i++){
if(rightParentheses == str.charAt(i))
{
rightCount++;
}
else if(leftParentheses == str.charAt(i))
{
leftCount++;
}
}
if(rightCount == leftCount){
return true;
}
else(rightCount != leftCount){
return false;
}
}
}());
The check is wrong, but You can fix it easily: In each step of the for loop the number of opening parenthesis cannot be smaller than the number of closing ones:
if (rightCount < leftCount)
return false;
The whole function should look like this:
function(str) {
var rightParentheses = '(';
var leftParentheses = ')';
var rightCount = 0;
var leftCount = 0;
for (var i = 0; i <= str.length; i++) {
if (rightParentheses == str.charAt(i))
rightCount++;
else if (leftParentheses == str.charAt(i))
leftCount++;
if (rightCount < leftCount)
return false;
}
return rightCount == leftCount;
}
If You'd like to generate all valid strings, you can use this function:
function nPair(n) {
if (n == 0)
return [""];
var result = [];
for (var i = 0; i < n; ++i) {
var lefts = nPair(i);
var rights = nPair(n - i - 1);
for (var l = 0; l < lefts.length; ++l)
for (var r = 0; r < rights.length; ++r)
result.push("(" + lefts[l] + ")" + rights[r]);
}
return result;
}
// result of nPair(3):
// ["()()()", "()(())", "(())()", "(()())", "((()))"]
Try this, i have modified your code a little bit. Modification and its explanation is marked in comments.
module.exports = Parentheses = (function() {
var _isParenthesesMatch = function(str) {
var parentheses = str.length;
var rightParentheses = '(';
var leftParentheses = ')';
var count=0;
for(i=0;i<str.length;i++){
//this is to check valid combination start always from ( and end with )
if(str.charAt(0)==rightParentheses && str.length-1==leftParentheses)
{
if(rightParentheses == str.charAt(i))
{
count++; //this will calculate how many times rightParentheses is present & increment count by 1
}
else if(leftParentheses == str.charAt(i))
{
count--; //this will simply decrement count to match valid sequence
}
}
if(count==0){
return true;
}
}
}());
Your function is wrong, try checking if left and right parenthesis and balanced:
function isValid(str){
var stripedStr = str.replace(/[^\(\)]+/g, '');
return stripedStr.split('').reduce(function(a, b){
return a > -1 ? b === '(' ? a + 1 : a - 1 : -1;
}, 0) === 0;
}
stripedStr - use replace() to remove any characters that are not ( or ).
split('') - returns an array so we can use reduce.
reduce() - applies a function against an accumulator and each value of the array (from left-to-right) has to reduce it to a single value.
The reduce starts with 0 as initial value and in the reduce function we count parenthesis
(+1 for (, -1 for ) )
Our string is valid if our counter never goes below 0 and we end up with 0.
You can write the reduce function like this too:
function(previousValue, currentValue){
if (previousValue > -1){
if (currentValue === '('){
return previousValue + 1;
} else {
return previousValue - 1;
}
}
return -1;
}
This is equivalent to:
function(a, b){
return a > -1 ? b === '(' ? a + 1 : a - 1 : -1;
}
It is wrong, because your function will return true for this example ))(( or this ())(()
I tried to rewrite this indexOf MDN example to practice recursion
var str = 'To be, or not to be, that is the question.';
var count = 0;
var pos = str.indexOf('e');
while (pos !== -1) {
count++;
pos = str.indexOf('e', pos + 1);
}
console.log(count); // displays 4
This was my solution:
var count = 0;
function countLetters(str, p) {
var pos = str.indexOf(p);
if (pos == -1) {
return count;
}
else {
count ++;
return countLetters(str.substr(pos + 1), p)
}
}
console.log(countLetters('To be, or not to be, that is the question.', 'e'));
It works, but is there anyway to get the count variable inside the function itself? Is it not really a true recursion if I have a count variable outside the function?
In a recursive function, if you want to keep a variable around from one "iteration" to the next, then you need to pass it as an argument:
function countLetters(str, p, count) {
count = count || 0;
var pos = str.indexOf(p);
if (pos == -1) {
return count;
}
else {
return countLetters(str.substr(pos + 1), p, count + 1);
}
}
console.log(countLetters('To be, or not to be, that is the question.', 'e'));
// => 4
However, this is not always necessary, as Arun P Johny's answer illustrates.
What you can do is to return the count value form the method, so if the item is not found you return 0, else you return 1 + value-of-recursive-call
function countLetters(str, p) {
var pos = str.indexOf(p);
if (pos == -1) {
return 0;
} else {
return 1 + countLetters(str.substr(pos + 1), p)
}
}
console.log(countLetters('To be, or not to be, that is the question.', 'e'));
Demo: Fiddle
i am trying to compare two arrays containing alphabets and numbers using jquery but a call to the function does nothing.
jQuery.compare = function (string2,string1) {
alert("comparing")
var i, j;
for ( i = 0, j=0; i < string2.length|| j<string1.length; ++i,++j) {
var n1 = 0,n2=0;
if ($.isNumeric(string2[i+1])) {
num=string2[i]
while ($.isNumeric(string2[i+1])) {
i++;
num += string2[i]
}
n1 = 1;
}
if ($.isNumeric(strin1[j])) {
num1 = string1[j]
while ($.isNumeric(string1[j+1])) {
j++;
num1 += string1[j]
}
n2 = 1;
}
if (n1 == 1) {
if (n2 = 1) {
if( parseInt(num1) - parseInt(num) !=0)
return parseInt(num1) - parseInt(num);
}
else
return 1;
}
else if (n2 = 1)
return -1;
else {
if(string2[i]-string1[j]!=0)
return string2[i]-string1[j]!=0;
}
}
if (j < string1.length)
return -1;
else
return 1;
}
Also i would like to know the best way to call this function. I would like to use something like string1.compare(string2) and replace string1 with 'this' in the above code fragment.
EDIT:
This is how i call the compare function.Here, colValues is an array of string.
$.fn.sort = function (colValues) {
alert("sorting")
var i;
for (i = 0; i < colValues.length; ++i) {
for (var j = 0; j < i - 1; ++j) {
alert("before compare")
if(colValues.compare(colValues[j],colValues[j + 1])) {
var temp = colValues[j];
colValues[j] = colValues[j + 1];
colValues[j + 1] = temp;
}
}
}
return colValues
}
if i replace
if(colValues.compare(colValues[j],colValues[j + 1]))
with
if(colValues[j]>colValues[j+1])
my sort function works.
i am a complete newbie at coding in jquery. There is probably some syntactical error. I dont really want any help with the algorithm just the syntax.
jsfiddle-checkout my code here
EDIT2:
i fixed everything thx to metadings.
heres what i had to change
1)
jQuery.compare
to
$.fn.compare
2)
if($.isNumeric(string2[i+1]))
to
if(jQuery.isNumeric(string2[i + 1]))
somehow the
while ($.isNumeric(string1[j+1]))
syntax worked without any changes
3)
parseInt(num1) - parseInt(num)
didnt work either as it returned NaN. To solve this problem i defined two var variables 'number1' and 'number2' and initialized them with 0's and assigned parseInt(num1) individually to the variables and then subtracted the new variables.