For loop without using for statement - javascript

I'm trying to write a program where you print a decrement by 1 loop, so if the value is 3 the output should be 3,2,1. But the output I get from this code is 3,2,1,0. Are there any ways I can fix this?
function loop(value) {
while(greaterThanZero(value) == true) {
printValue(value);
value = reduceOne(value);
console.log(value);
value--;
}
}
var value = 3;
var greaterThanZero = function (n) {
return n > 0;
}
var reduceOne = function (n) {
return n - 1;
}
var printValue = function (n) {
console.log(n)
}

You're doing the same thing twice in each iteration (logging and decrementing). Remove the two duplicate statements so you can break out immediately instead of going two at a time.
function loop(value) {
while(greaterThanZero(value) == true) {
console.log(value);
value--;
}
}
var greaterThanZero = function (n) {
return n > 0;
}
loop(3)

The function seems to be working as expected but you are seeing 0 because of this console.log(value). It is just logging the value after decrementing it
var value = 3;
var greaterThanZero = function(n) {
return n > 0;
}
var reduceOne = function(n) {
return n - 1;
}
var printValue = function(n) {
console.log(n)
}
function loop(value) {
while (greaterThanZero(value) == true) {
printValue(value);
value = reduceOne(value);
//console.log(value);
//value--;
}
}
loop(value)

Related

Counting values of a stack using a javascript algorithm

I need help figuring out how to make a JavaScript algorithm that count the values of a stack, I am given 3 custom methods
stack - a Stack object containing zero or more values.
.pop() which pops the top value of the stack
.push() which pushes a value on to the stack
.peek() which shows me the top value of the stack without modifying the stack
I tried simply returning the length of said stack like so
function countValues(stack) {
return stack.length
}
but i get back undefined thus having no success
this is the stack class that was used to implement the custom methods
class Stack {
constructor(...values) {
const data = {};
let index = 0;
this.push = function (value) {
if (arguments.length < 1) {
throw new TypeError('stack.push() requires a value argument');
}
if (typeof value === 'undefined') {
throw new TypeError('stack.push(value) received undefined');
}
data[index] = value;
index++;
};
this.pop = function () {
const last = index - 1;
if (last < 0) return;
const value = data[last];
delete data[last];
index = last;
return value;
};
this.peek = function () {
const last = index - 1;
if (last < 0) return;
return data[last];
};
this.print = function () {
if (index === 0) {
return 'Stack { <empty> }';
}
let output = ' }';
let last = index - 1;
for (; last > 0; last--) {
output = ' <- ' + JSON.stringify(data[last]) + output;
}
output = JSON.stringify(data[last]) + output;
return 'Stack { ' + output;
};
for (let i = 0; i < values.length; i++) {
this.push(values[i]);
}
Object.freeze(this);
}
}
class Stack {
constructor(...values) {
const data = {};
let index = 0;
this.push = function(value) {
if (arguments.length < 1) {
throw new TypeError('stack.push() requires a value argument');
}
if (typeof value === 'undefined') {
throw new TypeError('stack.push(value) received undefined');
}
data[index] = value;
index++;
};
this.pop = function() {
const last = index - 1;
if (last < 0) return;
const value = data[last];
delete data[last];
index = last;
return value;
};
this.peek = function() {
const last = index - 1;
if (last < 0) return;
return data[last];
};
this.print = function() {
if (index === 0) {
return 'Stack { <empty> }';
}
let output = ' }';
let last = index - 1;
for (; last > 0; last--) {
output = ' <- ' + JSON.stringify(data[last]) + output;
}
output = JSON.stringify(data[last]) + output;
return 'Stack { ' + output;
};
for (let i = 0; i < values.length; i++) {
this.push(values[i]);
}
Object.freeze(this);
}
}
const myStack = new Stack(1, 2, 3, 4, 5);
// Here's an easy but not so good way:
function countValues1(stack) {
return Array.from(stack.print()).filter(x => x === "<").length + 1;
}
// Here's another way, but it mutates the stack:
function countValues2(stack) {
let count = 0;
while (true) {
if (stack.pop() === undefined) {
break;
}
count++;
}
return count;
}
console.log(countValues1(myStack));
console.log(countValues2(myStack));
Without knowing exactly how stack works, or specifically what you need (are you allowed to modify the stack implementation? are you allowed to mutate the contents of the stack?) we'll struggle for a good answer, but the above should help get you maybe slightly closer perhaps.
Maybe this can help you doing a length function manually.
You should check how you declared your stack, .length is supposed to be working.
function countValues(stack) {
const tempStack = stack;
var length=0;
while(tempStack.pop()!=undefined){
length++;
}
return length;
}
This function allows you to run it and still keeping your data in the original stack.
length is a getter, which is essentially a function posing as a property. It will just return undefined if you call it on an object that doesn't implement it. If the exercise -- I assume that's what it is -- says you can only use the abovementioned methods, then you can't use object.length.

Counting odd and even numbers function issue

I want to provide function which will return object with odd and even numbers. Example: parseNum(12345) // Object{odd: 3, even:2}. I've got my code, but I don't understand why it's not working. Where is the problem?
function parseNum(num) {
var obj = {
odd: 0,
even: 0
};
var arr = Array.from(num);
arr.forEach(function(value) {
if (value % 2 === 0) {
obj.odd += 1;
} else {
obj.even += 1;
}
});
return obj;
}
Your answer is not working because a number is not iterable, you should cast it to string first.
function parseNum(num) {
var obj = {
odd: 0,
even: 0
};
if (typeof num === 'number') {
num = num.toString();
}
var arr = Array.from(num);
arr.forEach(function(value) {
if (value % 2 === 0) {
obj.odd += 1;
} else {
obj.even += 1;
}
});
return obj;
}
I think it's easier
function parseNum(num) {
const odd = Math.floor(num / 2);
const even = num - odd;
return {
odd,
even
}
}

JavaScript Return isn't returning

I wrote a simple function checking if an array contains duplicates, I want it to return true if it does and false if it doesn't.
function containsDuplicates(a) {
var hash = {};
a.forEach((elem, index) => {
if (hash[elem] === undefined) {
hash[elem] = 1;
} else {
console.log('true')
return true;
}
if (index === a.length - 1) {
console.log('false')
return false;
}
})
}
var arr = [1, 2, 3, 4];
containsDuplicates(arr)
My console.log logs just fine but it doesn't seem to be hitting the return. My entire function returns undefined every time. Why is this the case?
You are returning from the callback that you passed to forEach().
You are returning from the callback you passed to foreach. You should try something like this instead.
function hasDuplicates(array) {
var keyStore = {};
for (var i = 0; i < array.length; ++i) {
var value = array[i];
if (value in keyStore) {
return true;
}
keyStore[value] = true;
}
return false;
}

Get return value of first function invocation match without invoking it twice

I have an array of function references.
I need to find the return value of the first function invocation that satisfies my match condition.
How can I avoid calling the matched function twice?
var f = function(x) { if (x === 10) return "ten"; }
var g = function(y) { if (y === 20) return "twenty"; }
var result = [f, g].find(m => m(10))
if (result) return result(10)
// this returns "ten"
Still not sure I fully understand you question. It seems to me that you want to iterate through an array of functions and return the result if the function called with the condition is truthy.
let fncaller = (fns, condition) => {
var result
for (var fn of fns) {
result = fn(condition)
if (result) { return result }
}
}
Can you use global variables?
var f = function(x) {
return x % 2 == 0
}
var g = function(y) {
return x % 2 == 1
}
var result = [f, g].find(function(m) {
window.blah = m(10);
return window.blah;
})
console.log(window.blah);
Or #DaveNewton's method. Not sure which is faster:
var f = function(x) {
if (x === 10) return "ten";
}
var g = function(y) {
if (y === 20) return "twenty";
}
var funcs = [f, g];
function checkIt(value) {
for (var i = 0, numFuncs = funcs.length; i < numFuncs; ++i) {
var v = funcs[i](value);
if (v) return v;
}
}
console.log(checkIt(20));
You could store in a variable as you go. It's better than using a global.
var f = function(x) { if (x === 10) return "ten"; };
var g = function(y) { if (y === 20) return "twenty"; };
function findValue(funcs, val) {
var result;
funcs.find(m => result = m(val));
return result;
}
console.log(findValue([f, g], 10));

Trying to return up a recursive combinations function without getting 'undefined'

When I call this with [1,2,3,4], it returns undefined and I'm not understanding why. The goal is for it to return true if any combination of numbers in the array add up to the maximum number in the array, and false if it's not possible.
function ArrayAdditionI(arr) {
var max = Math.max.apply(null, arr);
arr.splice(arr.indexOf(max), 1);
var sum = function(arr) { return arr.reduce(function(a,b) { return a + b; }); };
function combos(arr) {
var f = function(prefix, arr) {
for (var i = 0; i < arr.length; i++) {
var clone = prefix.slice(0);
clone.push(arr[i]);
if (sum(clone) == max) { return true; }
return f(clone, arr.slice(i+1));
}
}
return f([], arr);
}
return combos(arr);
}
f is returning undefined when it is called with an empty arr! You will need to explicitly return false if none of the tests in the loop returned from the function. And you must not return false on the first occasion of the loop, but break only when you found true and continue the loop elsewhile.
To fix this, you'd have something like
function combos(arr) {
function f(prefix, arr) {
for (var i = 0; i < arr.length; i++) {
var clone = prefix.slice(0);
clone.push(arr[i]);
if (sum(clone) == max) return true;
if (f(clone, arr.slice(i+1))) return true;
}
return false;
}
return f([], arr);
}
However, also your recursion scheme with the loop looks a bit complicated. I would rather go with the naive enumeration of the "binary tree", where the nodes of each level decide whether the current item will be included in the to-be-tested subset:
function ArrayAdditionI(arr) {
var max = Math.max.apply(null, arr);
arr.splice(arr.indexOf(max), 1);
var sum = function(arr) { return arr.reduce(function(a,b) { return a + b; }, 0); };
function f(subset, arr) {
return arr.length
? f(subset, arr.slice(1)) || f(subset.concat([arr[0]]), arr.slice(1))
: sum(subset) == max
}
return f([], arr);
}
It seems that you don't test all the possible combination.
Here you will test 1+2+3, 2+3, 3 but never 1+3.
Do you really want to have a recursive function here ?
There may be some more simple way to find that.
function ArrayAdditionI(arr) {
var max = Math.max.apply(null, arr);
arr.splice(arr.indexOf(max), 1);
var res = arr.filter(function(num, idx) {
var combination = false;
// Check all combination non previously tested
for (var i = idx; i < arr.length - 1; i++) {
if (num + arr[i+1] === max) {
combination = true;
break;
}
}
return combination;
});
return res.length > 0;
}
The problem is your f function is not ever hitting the
if (sum(clone) == max) { return true; }
line of code so it will just keep recursively calling until arr.length == 0 and it will return undefined.
Your variables torf and results are unused, maybe you forgot to do something with them?

Categories

Resources