Beginner question: returning number value from string - javascript

If I give a value to firstParam as 'Ten' or '10' is there some way I can make the program return a number value to the function?
const sum = (firstParam, secondParam) => {
if (firstParam === Number(firstParam) && secondParam === Number(secondParam))
return (firstParam - secondParam)
else
return ('Invalid argument(s)')
}
console.log(sum(1,1))
EDIT
I have tried many different ways changing the firstParam to Number.firstParam, when i get close i miss out on the correct return statements
const sum = (firstParam, secondParam) =>{
firstParam = Number.firstParam
if (firstParam === Number(firstParam) && secondParam === Number(secondParam) )
return (firstParam - secondParam);
else
return ('Invalid argument(s)')
}
console.log(sum(1,1))

You need to check the type of the arguments before trying to convert them to a number:
const sum = (firstParam, secondParam) => {
// If both are numbers everything is ok
if (typeof firstParam === 'number' && typeof secondParam === 'number' ) {
return (firstParam - secondParam);
}
// If are stingified numebrs we convert them
const firstParamInNumber = parseFloat(firstParam)
const secondParamInNumber = parseFloat(secondParam)
return isNaN(firstParamInNumber) || isNaN(secondParamInNumber) ? 'Invalid argument(s)' : firstParamInNumber - secondParamInNumber
}
console.log(sum(1,'1'))
console.log(sum(1,1))
console.log(sum(1,'wrong param'))

If you provide a number in form of string. for example '10'.
You can parse it into Number and then return the sum as shown below.
Example when both arguments are correct.
const sum = (firstParam, secondParam) =>{
let sum = Number(firstParam)+Number(secondParam);
return Number(sum)?sum:"Invalid argument(s)";
}
console.log(sum('10','1'))
Example when anyone of the argument is incorrect.
const sum = (firstParam, secondParam) =>{
let sum = Number(firstParam)+Number(secondParam);
return Number(sum)?sum:"Invalid argument(s)";
}
console.log(sum('ten','1'))

Related

I'm trying to get "Hi I am David , and the number is even" shown on the console, but every time I ran the code "even" is shown as a number

first part sums two numbers, second part checks whether the sum of the numbers is odd or even and the final part prints out the message but in this case it prints out 8 instead of even
let sum = (a, b) => {
return a + b};
let evaluate = (c) => {
if (c % 2 == 0) {
console.log("Even")
} else {
console.log("odd")
}
return c;
};
let Hello = (name, status) => {
let message = `Hi I am ${name} , and the number is ${status}`;
return message;
};
console.log( Hello("David", evaluate(sum(5, 3))));
As Sergey mentions above, returning a console.log is not the same as returning a string.
I've re-written your code to return a string and it should now behave as expected.
let sum = (a, b) => {
return a + b};
let evaluate = (c) => {
if (c % 2 == 0) {
return "Even";
}
return "Odd";
};
let Hello = (name, status) => {
let message = `Hi I am ${name} , and the number is ${status}`;
return message;
};
console.log( Hello("David", evaluate(sum(5, 3))));

Enabling multiple operations in a calculator via vanilla js

I'm trying to practice my js and I'm doing a calculator project. I've got it to work but I can only do one calculation. I'm stuck and I need to be able to carry out multiple operations. Please note I'm not yet done with the project and so i'm testing for functionality, also some buttons are yet to be worked on. I've also been advised not to use eval() method.
Here is what I need help with:
** Users should be able to string together several operations and get the right answer, with each pair of numbers being evaluated at a time. For example, 12 + 7 - 5 * 3 = should yield 42.**
let add = function(a,b) {
return a + b;
}
let subtract = function(a,b) {
return a - b;
}
let multiply = function(a,b) {
return a * b;
}
let divide = function(a,b) {
return a / b;
}
let operator = function(operate,a,b) {
if (operate === '+') {
return add(a,b);
} else if (operate === '-') {
return subtract(a,b);
} else if (operate === '*') {
return multiply(a,b);
} else if (operate === '/') {
return divide(a,b);
}
}
let screen = document.querySelector('div');
let buttons = document.querySelector('.btns');
let data = ''
let numOne = ''
let numTwo = ''
let result = ''
let operatorSymbol = ''
buttons.addEventListener('click', e => {
data += e.target.value;
screen.textContent = data;
if ((e.target.value === '+') || (e.target.value === '-') || (e.target.value === '*') ||
(e.target.value === '/')){
numOne = data.slice(0,-1);
operatorSymbol += e.target.value;
}
numTwo = data.slice(-((data.length-1) - numOne.length));
if(e.target.value === '='){
data=data.slice(0,-1);
numTwo=numTwo.slice(0,-1);
result=operator(operatorSymbol,+numOne,+numTwo);
data = result;
screen.textContent = data;
}
})
The full webpage can be found here : https://repl.it/#socman/SweetZealousLearning#app.js
Any help will be appreciated. Thanks!
So basically you end up with a string like "12+7-5*3". One option is to use regex to parse the string and do the math on the resulting array. This is not the only way, but for simple equations like the ones you have, it should work.
// Perform math operation on 2 values
function doMath(op1, op, op2)
{
if (op === '+') return op1 + op2;
if (op === '-') return op1 - op2;
if (op === '*') return op1 * op2;
if (op === '/') return op1 / op2;
return 0; // error
}
// Test string
const eq = "12+7-5*3";
// Parse with regex
const regex = /\d+|[-+\*\/]/g;
const parsed = eq.match(regex);
// Store first number (12 in the example)
if (parsed && parsed.length && !isNaN(parsed[0])) {
let result = Number(parsed[0]);
for (let i = 1; i < eq.length - 1; i++) {
// Do the math with previous result and next number
if ("+-*/".includes(parsed[i]) && !isNaN(parsed[i+1])) {
result = doMath(result, parsed[i], Number(parsed[i+1]));
}
}
console.log(result);
}

Returning a string based off of an objects key value pairs

I currently receive an object from a payload that I'm looking to format essentially into a string based off the values inside that object. I have a solution but I'm not really a big fan of it and know there is likely a more practical way of solving this.
the object that comes back in the payload looks like this
{
sundayUsage: false,
mondayUsage: true,
tuesdayUsage: false,
wednesdayUsage: true,
thursdayUsage: true,
fridayUsage: true,
saturdayUsage: false
}
Based off of these values I want to be able to display a different string.
Here is my current solution
function formatSchedule(schedule) {
let days = []
let convertedSchedule = Object.keys(schedule).map(x => ({
available: schedule[x],
label: x.slice(0, 3).replace(/^[^ ]/g, match => match.toUpperCase())
}))
convertedSchedule.map(x => {
if (x.available) {
days.push(x.label)
}
return days
})
if (
days.includes('Mon' && 'Tue' && 'Wed' && 'Thu' && 'Fri' && 'Sat' && 'Sun')
) {
return 'Everyday'
} else if (
days.includes('Mon' && 'Tue' && 'Wed' && 'Thu' && 'Fri') &&
!days.includes('Sat' && 'Sun')
) {
return 'Weekdays (Mon-Fri)'
} else if (
days.includes('Sat' && 'Sun') &&
!days.includes('Mon' && 'Tue' && 'Wed' && 'Thu' && 'Fri')
) {
return 'Weekends (Sat-Sun)'
} else return days.join(', ')
}
I don't feel like bringing in an external library is the necessary, but I am open to looking into suggestions if it ends up being the right tool for the job.
Slightly different approach, using Boolean as the function passed to some/every:
function formatSchedule(schedule) {
const days = Object.values(schedule);
const weekdays = days.slice(0, 5);
const weekend = days.slice(-2);
if (days.every(Boolean)) return 'Everyday';
else if (weekdays.every(Boolean) && !weekend.some(Boolean)) return 'Weekdays (Mon-Fri)'
else if (weekend.every(Boolean) && !weekdays.some(Boolean)) return 'Weekends (Sat-Sun)'
else return Object.entries(schedule)
.filter(v => v[1])
.map(v => v[0][0].toUpperCase() + v[0].slice(1, 3))
.join(', ');
}
I'd do (big parts can be reused):
const days = ["monday", "tuesday", "wednesday", ,"thursday", "friday", "saturday", "sunday"];
const weekdays = days.slice(0, 5);
const weekend = days.slice(5);
const every = (a, b) => a.every(it => b.includes(it));
const some = (a, b) => a.some(it => b.includes(it));
const capitalize = s => s[0].toUpperCase() + s.slice(1);
const available = days.filter(day => obj[day + "Usage"]);
if(available.length === days.length)
return "Everyday";
if(every(weekdays, available) && !some(weekend, available))
return "Weekday";
if(every(weekend, available) && !some(weekdays, available))
return "Weekend";
return available.map(it => capitalize(it.slice(0, 3))).join(", ");
Note that this
days.includes('Sat' && 'Sun')
will evaluate the && first and result in the last value (if all values before were truthy, all non empty strings are truthy), so its the same as:
days.includes('Sun')
and thats obviously not what you want.
Given that your object just contains booleans as values, why not just use that for the conditions ?
function formatSchedule(schedule){
if(schedule.monday&&schedule.tuesday&&schedule.wednesday&&schedule.thursday&&schedule.friday&&schedule.saturday&&schedule.sunday)
return "Everyday"
if((schedule.monday&&schedule.tuesday&&schedule.wednesday&&schedule.thursday&&schedule.friday)&&!(schedule.saturday||schedule.sunday))
return "Weekdays"
if(!(schedule.monday||schedule.tuesday||schedule.wednesday||schedule.thursday&&schedule.friday)&&(schedule.saturday&&schedule.sunday))
return "Weekends"
// Get keys here and return days if other coditions aren't matched here.
}

closure in javascript with multiple empty calls to sum function

I faced this question in one interview. I did not get how to solve this.
Question: Write a sum function which will add 2 numbers, but numbers can be passed to a function in following ways:
sum(3)(4) // answer should be 7
sum(3)()(4)//answer should be 7
sum(3)()()()()(4) //answer should b 7
I can solve first function using closure, in fact for the second function also I can check the arguments and if arguments length is zero I can again make a call to sum to except next parameter.
But how to make it generic ? Means even your first parameter and last parameter has 'N' number of calls & those can be empty or parameterized, it should return sum.
Recorded a video how to solve it:
https://youtu.be/7hnYMIOVEg0
Text answer:
function sum(numberOne) {
return function innerSum(numberTwo) {
if (typeof(numberTwo) === 'number') {
return numberOne + numberTwo;
}
return innerSum;
}
}
Output:
sum(3)(4); => 7
sum(5)()()(10); => 15
Basically, you need to return inner function (innerSum) up until you receive a value - then you return number.
You could also choose another name - like _sum(), or addToFirstNumber() for your method.
You can always return a function from within a function:
let a;
function sum(value) {
if (typeof value !== "number") {
return sum;
}
if (typeof a !== "number") {
a = value;
return sum;
}
let result = a + value;
a = null;
return result;
}
see https://jsfiddle.net/d9tLh11k/1/
function sum(num1) {
return function sum2(num2) {
if(num2 === undefined) {
return sum2;
}
return num1 + num2;
}
}
console.log(sum(4)()()()(3)); // -> 7
Or in ES6:
const add = num1 => num2 => num2 === undefined ? add(num1) : num1 + num2;
console.log(add(4)()()()()()(3)); // -> 7
function add (n) {
var func = function (x) {
if(typeof x==="undefined"){
x=0;
}
return add (n + x);
};
func.valueOf = func.toString = function () {
return n;
};
return func;
}
console.log(+add(1)(2)(3)()()(6));
I have already given answer of this question Here
but according to your question I have modified that
function add (n) {
var func = function (x) {
if(typeof x==="undefined"){
x=0;
}
return add (n + x);
};
func.valueOf = func.toString = function () {
return n;
};
return func;
}
console.log(+add(1)(2)(3)()()(6));
Run code like that
console.log(+add(1)(2)(3)()()(6));
This should do it
function sum(num1) {
if (arguments.length === 0){
return sum;
}
return function innerSum(num2) {
if (arguments.length > 0){
return num1 + num2;
}else{
return innerSum;
}
}
}
You can do this in a number of ways, but mostly you'll want named recursion. That is, you can have something like:
sum = start => (...args) => args.length? args[0] + start : sum(start)
but it might look cleaner to write this as:
function sum(start) {
function out(...args) {
return args.length? start + args[0] : out
}
return out;
}

Variadic curried sum function

I need a js sum function to work like this:
sum(1)(2) = 3
sum(1)(2)(3) = 6
sum(1)(2)(3)(4) = 10
etc.
I heard it can't be done. But heard that if adding + in front of sum can be done.
Like +sum(1)(2)(3)(4). Any ideas of how to do this?
Not sure if I understood what you want, but
function sum(n) {
var v = function(x) {
return sum(n + x);
};
v.valueOf = v.toString = function() {
return n;
};
return v;
}
console.log(+sum(1)(2)(3)(4));
JsFiddle
This is an example of using empty brackets in the last call as a close key (from my last interview):
sum(1)(4)(66)(35)(0)()
function sum(firstNumber) {
let accumulator = firstNumber;
return function adder(nextNumber) {
if (nextNumber === undefined) {
return accumulator;
}
accumulator += nextNumber;
return adder;
}
}
console.log(sum(1)(4)(66)(35)(0)());
I'm posting this revision as its own post since I apparently don't have enough reputation yet to just leave it as a comment. This is a revision of #Rafael 's excellent solution.
function sum (n) {
var v = x => sum (n + x);
v.valueOf = () => n;
return v;
}
console.log( +sum(1)(2)(3)(4) ); //10
I didn't see a reason to keep the v.toString bit, as it didn't seem necessary. If I erred in doing so, please let me know in the comments why v.toString is required (it passed my tests fine without it). Converted the rest of the anonymous functions to arrow functions for ease of reading.
New ES6 way and is concise.
You have to pass empty () at the end when you want to terminate the call and get the final value.
const sum= x => y => (y !== undefined) ? sum(x + y) : x;
call it like this -
sum(10)(30)(45)();
Here is a solution that uses ES6 and toString, similar to #Vemba
function add(a) {
let curry = (b) => {
a += b
return curry
}
curry.toString = () => a
return curry
}
console.log(add(1))
console.log(add(1)(2))
console.log(add(1)(2)(3))
console.log(add(1)(2)(3)(4))
Another slightly shorter approach:
const sum = a => b => b? sum(a + b) : a;
console.log(
sum(1)(2)(),
sum(3)(4)(5)()
);
Here's a solution with a generic variadic curry function in ES6 Javascript, with the caveat that a final () is needed to invoke the arguments:
const curry = (f) =>
(...args) => args.length? curry(f.bind(0, ...args)): f();
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1)() == 5 // true
Here's another one that doesn't need (), using valueOf as in #rafael's answer. I feel like using valueOf in this way (or perhaps at all) is very confusing to people reading your code, but each to their own.
The toString in that answer is unnecessary. Internally, when javascript performs a type coersion it always calls valueOf() before calling toString().
// invokes a function if it is used as a value
const autoInvoke = (f) => Object.assign(f, { valueOf: f } );
const curry = autoInvoke((f) =>
(...args) => args.length? autoInvoke(curry(f.bind(0, ...args))): f());
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1) + 0 == 5 // true
Try this
function sum (...args) {
return Object.assign(
sum.bind(null, ...args),
{ valueOf: () => args.reduce((a, c) => a + c, 0) }
)
}
console.log(+sum(1)(2)(3,2,1)(16))
Here you can see a medium post about carried functions with unlimited arguments
https://medium.com/#seenarowhani95/infinite-currying-in-javascript-38400827e581
Try this, this is more flexible to handle any type of input. You can pass any number of params and any number of paranthesis.
function add(...args) {
function b(...arg) {
if (arg.length > 0) {
return add(...[...arg, ...args]);
}
return [...args, ...arg].reduce((prev,next)=>prev + next);
}
b.toString = function() {
return [...args].reduce((prev,next)=>prev + next);
}
return b;
}
// Examples
console.log(add(1)(2)(3, 3)());
console.log(+add(1)(2)(3)); // 6
console.log(+add(1)(2, 3)(4)(5, 6, 7)); // 28
console.log(+add(2, 3, 4, 5)(1)()); // 15
Here's a more generic solution that would work for non-unary params as well:
const sum = function (...args) {
let total = args.reduce((acc, arg) => acc+arg, 0)
function add (...args2) {
if (args2.length) {
total = args2.reduce((acc, arg) => acc+arg, total)
return add
}
return total
}
return add
}
document.write( sum(1)(2)() , '<br/>') // with unary params
document.write( sum(1,2)() , '<br/>') // with binary params
document.write( sum(1)(2)(3)() , '<br/>') // with unary params
document.write( sum(1)(2,3)() , '<br/>') // with binary params
document.write( sum(1)(2)(3)(4)() , '<br/>') // with unary params
document.write( sum(1)(2,3,4)() , '<br/>') // with ternary params
ES6 way to solve the infinite currying. Here the function sum will return the sum of all the numbers passed in the params:
const sum = a => b => b ? sum(a + b) : a
sum(1)(2)(3)(4)(5)() // 15
function add(a) {
let curry = (b) => {
a += b
return curry;
}
curry[Symbol.toPrimitive] = (hint) => {
return a;
}
return curry
}
console.log(+add(1)(2)(3)(4)(5)); // 15
console.log(+add(6)(6)(6)); // 18
console.log(+add(7)(0)); // 7
console.log(+add(0)); // 0
Here is another functional way using an iterative process
const sum = (num, acc = 0) => {
if !(typeof num === 'number') return acc;
return x => sum(x, acc + num)
}
sum(1)(2)(3)()
and one-line
const sum = (num, acc = 0) => !(typeof num === 'number') ? acc : x => sum(x, acc + num)
sum(1)(2)(3)()
You can make use of the below function
function add(num){
add.sum || (add.sum = 0) // make sure add.sum exists if not assign it to 0
add.sum += num; // increment it
return add.toString = add.valueOf = function(){
var rtn = add.sum; // we save the value
return add.sum = 0, rtn // return it before we reset add.sum to 0
}, add; // return the function
}
Since functions are objects, we can add properties to it, which we are resetting when it's been accessed.
we can also use this easy way.
function sum(a) {
return function(b){
if(b) return sum(a+b);
return a;
}
}
console.log(sum(1)(2)(3)(4)(5)());
To make sum(1) callable as sum(1)(2), it must return a function.
The function can be either called or converted to a number with valueOf.
function sum(a) {
var sum = a;
function f(b) {
sum += b;
return f;
}
f.toString = function() { return sum }
return f
}
function sum(a){
let res = 0;
function getarrSum(arr){
return arr.reduce( (e, sum=0) => { sum += e ; return sum ;} )
}
function calculateSumPerArgument(arguments){
let res = 0;
if(arguments.length >0){
for ( let i = 0 ; i < arguments.length ; i++){
if(Array.isArray(arguments[i])){
res += getarrSum( arguments[i]);
}
else{
res += arguments[i];
}
}
}
return res;
}
res += calculateSumPerArgument(arguments);
return function f(b){
if(b == undefined){
return res;
}
else{
res += calculateSumPerArgument(arguments);
return f;
}
}
}
let add = (a) => {
let sum = a;
funct = function(b) {
sum += b;
return funct;
};
Object.defineProperty(funct, 'valueOf', {
value: function() {
return sum;
}
});
return funct;
};
console.log(+add(1)(2)(3))
After looking over some of the other solutions on here, I would like to provide my two solutions to this problem.
Currying two items using ES6:
const sum = x => y => (y !== undefined ) ? +x + +y : +x
sum(2)(2) // 4
Here we are specifying two parameters, if the second one doesnt exist we just return the first parameter.
For three or more items, it gets a bit trickier; here is my solution. For any additional parameters you can add them in as a third
const sum = x => (y=0) => (...z) => +x + +y + +z.reduce((prev,curr)=>prev+curr,0)
sum(2)()()//2
sum(2)(2)()//4
sum(2)(2)(2)//6
sum(2)(2)(2,2)//8
I hope this helped someone

Categories

Resources