Ordering arguements alphebetically and printing a number depending on the order - javascript

So I'm new to Javascript, just finished a small free online crash course that covers the bare bones basics but I'm still pretty clueless.
Found TwilioQuest that takes problems and gets the player to solve them in a game format.
One issue has me at the mercy of the same 11 lines of code.
The task is write a script that will take two command line arguments - a pair of strings that should be compared to see which one comes first alphabetically (letter casing is not important). The script should determine if the first string is before, after, or in the same position (equal) to the second string, alphabetically. For each case, you should print out a number with console.log.
When the first argument is earlier in the alphabet than the second, your script should print -1.
When the first argument is the same as the second, your script should print 0.
When the first argument is later in the alphabet than the second, your function should print 1.
This is what I have right now and I'm being told that its false or that it doesn't work
const firstValue = process.argv[2];
const secondValue = process.argv[3];
if ((firstValue.toLowerCase() < secondValue.toLowerCase())) {
console.log(-1)
};
if ((firstValue > secondValue)) {
console.log(1);
};
if ((firstValue.ignoreCase == secondValue.ignoreCase)) {
console.log(0);
};
I have tried nesting the conditional operator and I'm still told its wrong

You're only doing the case-insensitive comparison in the first condition. toLowerCase() doesn't modify the string, so you need to do it in all the comparisons.
But it's easier if you do it once when assigning the variables.
const firstValue = process.argv[2].toLowerCase();
const secondValue = process.argv[3].toLowerCase();
if (firstValue < secondValue) {
console.log(-1);
} else if (firstValue == secondValue) {
console.log(0);
} else {
console.log(1);
}
When you have a series of mutually exclusive tests, you should use else if and else so it doesn't perform unnecessary tests.

you can use charCodeAt() it provides the ascii value of a string character
const firstValue = process.argv[2];
const secondValue = process.argv[3];
firstValue.toLowerCase()
secondValue.toLowerCase()
if ((firstValue.charCodeAt(0) < secondValue.charCodeAt(0))) {
console.log(-1)
};
if ((firstValue.charCodeAt(0) > secondValue.charCodeAt(0))) {
console.log(1);
};
if ((firstValue.charCodeAt(0) == secondValue.charCodeAt(0))) {
console.log(0);
};
hope this solves your problem

Related

Simple javascript function not working as expected. Why?

For some reason, no matter what I bind to the variable theNumber, I still get the console outputting the first console.log() inside of the numberCheck(). I expected this to output the second console.log(), but it refuses. I have tried many different syntactical changes. Maybe I just don't understand the expression !Number.isNaN(). I thought that this meant if the number is a number than its true, but I might be wrong.
Keep in mind, I'm new. I understand terminology so feel free to communicate with whatever words. But my javascript logic is subpar.
let theNumber = 'god'
function numberCheck(x) {
if (!Number.isNaN(x)) {
console.log('You picked a number')
}
else {
console.log('why won't this log');
}
}
numberCheck(theNumber)
numberCheck(12)
The output:
You picked a number
You picked a number
FIXED and Working as Expected:
let theNumber = 'god'
function numberCheck(x) {
if (isNaN(x)) {
console.log('You picked a number')
}
else {
console.log('why wont this log');
}
}
numberCheck(theNumber)
numberCheck(12)
The output:
why wont this log
You picked a number
In JS NaN is a value that differs from a type to another, basically NaN for strings, NaN for ints etc, what that method is doing is checking if the passed value is a NaN of type Number.
You have to cast the argument x to a number
let theNumber = 'god'
function numberCheck(x) {
if (!Number.isNaN(Number(x))) {
console.log('You picked a number');
} else {
console.log('why won\'t this log');
}
}
numberCheck(theNumber);
numberCheck(12);
Using "isNaN" function can be tricky sometimes (see this part of the documentation "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN").
Since it seems you want just verify if a variable is a number or not, you can make it that way:
var theNumber = 100;
function numberCheck(x){
if(typeof x === 'number'){
console.log('Nice you picked a number');
}else{
console.log('It is not a number');
}
}
numberCheck(theNumber);
"typeof" function will return the type of the variable "x".

continually add values in javascript with while loop

I'm a newbie to Javascript so please bear with me for this basic question,
I'm trying to get my function to add all the individual digits in a string together, and then keep doing this until I'm left with a single digit!
3253611569939992595156
113 // result of the above digits all added together
5 //result of 1+1+3
I've created a while loop, but it only adds the numbers together once, it dosn't repeat until a single digit and I can't work out why!
function rootFunc(n) {
var splite = n.toString().split('').map(x => Number(x)); //converts the number to a string, splits it and then converts the values back to a number
while (splite.length > 1) {
splite = splite.reduce(getSum);
}
return splite;
}
console.log(rootFunc(325361156993999259515));
function getSum(total, num) {
return total + num;
}
You're reducing properly, but what you're not doing is re-splitting. Try breaking this out into separate functions:
function digits(n) {
return n.toString().split('').map(x =>Number(x));
}
Then split each time:
function rootFunc(n) {
var d = digits(n);
while (d.length > 1) {
d = digits(d.reduce(getSum));
}
return d;
}
The problem here is that you return the result after the first splice. You need to have a recursive function. To do this, you can put this before the return :
if(splite > 9) splite = rootFunc(splite);
This way, you check if the result is greater than 10, if not you do the function with the remaining digits
I was looking this over in jsfiddle, and your number isn't being passed to exact precision, so just console logging n as soon as you call rootFunc, you've already lost data. Otherwise, to fix your loop, you need to remap splite to a string before the end of your codeblock since your while statement is checking .length, which needs to be called on a string. Put this piece of code at the end of the block:
splite = splite.toString().split('').map(x =>Number(x));

Devide numbers on countup function

I'm starting to learn javascript and I basically needed a countup that adds an x value to a number(which is 0) every 1 second. I adapted a few codes I found on the web and came up with this:
var d=0;
var delay=1000;
var y=750;
function countup() {
document.getElementById('burgers').firstChild.nodeValue=y+d;
d+=y;
setTimeout(function(){countup()},delay);
}
if(window.addEventListener){
window.addEventListener('load',countup,false);
}
else {
if(window.attachEvent){
window.attachEvent('onload',countup);
}
}
There's probably residual code there but it works as intended.
Now my next step was to divide the resultant string every 3 digits using a "," - basically 1050503 would become 1,050,503.
This is what I found and adapted from my research:
"number".match(/.{1,3}(?=(.{3})+(?!.))|.{1,3}$/g).join(",");
I just can't find a way to incorporate this code into the other. What should I use to replace the "number" part of this code?
The answer might be obvious but I've tried everything I knew without sucess.
Thanks in advance!
To use your match statement, you need to convert your number to a String.
Let's say you have 1234567.
var a = 1234567;
a = a + ""; //converts to string
alert(a.match(/.{1,3}(?=(.{3})+(?!.))|.{1,3}$/g).join(","));
If you wish, you can wrap this into a function:
function baz(a) {
a = a + "";
return a.match(/.{1,3}(?=(.{3})+(?!.))|.{1,3}$/g).join(",");
}
Usage is baz(1234); and will return a string for y our.
While I do commend you for using a pattern matching algorithm, this would probably be easier to, practically speaking, implement using a basic string parsing function, as it doesn't look anywhere as intimidating from just looking at the match statement.
function foo(bar) {
charbar = (""+bar).split(""); //convert to a String
output = "";
for(x = 0; x < charbar.length; x++) { //work backwards from end of string
i = charbar.length - 1 - x; //our index
output = charbar[i] + output; //pre-pend the character to the output
if(x%3 == 2 && i > 0) { //every 3rd, we stick in a comma, except if it is not the leftmost digit
output = ',' + output;
}
}
return output;
}
Usage is basically foo(1234); which yields 1,234.

Recursion and Loops - Maximum Call Stack Exceeded

I'm trying to build a function that adds up all the numbers within a string... for example, 'dlsjf3diw62' would end up being 65.
I tried to be clever and put together a recursive function:
function NumberAddition(str) {
var numbers='1234567890';
var check=[];
str=str.split[''];
function recursive(str,check) {
if (str.length==0)
return check;
else if (numbers.indexOf(str[0])>=0)
{
for (i=0;i<str.length;i++){
if (numbers.indexOf(str[i])<0)
check.push(str.slice(0,i));
str=str.slice(i);
return recursive(str,check);
}
}
else
str.shift();
return recursive(str,check);
}
You'll see that I'm trying to get my numbers returned as an array in the array named check. Unfortunately, I have a maximum call stack size exceeded, and I'm not sure why! The recursion does have a base case!! It ends once str no longer has any contents. Why wouldn't this work? Is there something I'm missing?
-Will
You can achieve the same thing with a far easier solution, using regular expressions, as follows:
var str = 'dlsjf3diw62';
var check = str.match(/\d+/g); // this pattern matches all instances of 1 or more digits
Then, to sum the numbers, you can do this:
var checkSum = 0;
for (var i = 0; i < check.length; i++) {
checkSum += parseInt(check[i]);
}
Or, slightly more compact:
var checkSum = check.reduce(function(sum, num){ return sum + parseInt(num) }, 0);
The reason your recursion doesn't work is the case where you do enter the for loop, because you've found a digit, but the digits continue to the end of the string. If that happens, the return inside the for loop never happens, and the loop ends. After that, the .shift() does not happen, because it's in that else branch, so you return re-process the same string.
You shouldn't solve this particular problem that way, but the code makes a good example of the anti-pattern of having return statements inside if bodies followed by else. Your code would be clearer (and would work) if it looked like this:
function recursive(str, check) {
if (str.length == 0)
return check;
if (numbers.indexOf(str[0]) >= 0) {
// Find the end of the string of digits, or
// the end of the whole thing
for (var i = 0; i < str.length && numbers.indexOf(str[i]) >= 0; i++);
check.push(str.slice(0, i));
str = str.slice(i);
return recursive(str, check);
}
// A non-digit character
str.shift();
return recursive(str, check);
}
In that version, there are no else clauses, because the two if clauses always involve a return. The for loop is changed to simply find the right value of "i" for the subsequent slicing.
edit — one thing this doesn't fix is the fact that you're pushing arrays into your "check" list. That is, the substring "62" would be pushed as the array ["6", "2"]. That's not a huge problem; it's solved with the addition of a .join() in the right place.

Decomposition of Javascript Class and Function Calls

I am creating a class to convert an integer to a sentence in a natural language. I've got some basic checks going on to ensure that the number given is between -9999 and 9999. I feel like this works for the most part.
However, once the program reaches "this.convertSentence" - past the try/catch block and error checking, I'm wondering what the best practice is now to decompose the problem into the various function calls it will need to run through to get the job done.
What I'm planning on doing with this.convertSentence is doing some checking for number size, etc...and then sending the number off to separate functions to do more work and having them propagate a sentence to return. I'm not sure if I want a variable just within my class to work with or whether I should be passing a variable around for the sentence to build. Things like this I am wondering about.
/**
* A class for converting an integer to a natrual language sentence in Spanish.
* Accepts integers from -9999 to 9999
*
*/
function NumberToWord () {
this.getSentence = function(number) {
// Check for erroneous input. Accepts only -9999 thru 9999 integers
try
{
if(number === parseInt(number) && number > -10000 && number < 10000) {
return this.convertSentence(number);
}
else {
throw new Error("Argument is not an integer between -9999 and 9999");
}
}
catch(e){
console.log(e.name + " " + e.message);
}
};
this.convertSentence = function(number) {
return "This is where I'll start the logic for the sentence";
};
}
var numberToWord = new NumberToWord();
// Tests
console.log(numberToWord.getSentence(9999));
console.log(numberToWord.getSentence(-9999));
console.log(numberToWord.getSentence(10000));
console.log(numberToWord.getSentence(-10000));
console.log(numberToWord.getSentence(0));
console.log(numberToWord.getSentence(1.1));
console.log(numberToWord.getSentence(-9999.1));
console.log(numberToWord.getSentence(10001));
console.log(numberToWord.getSentence(-10001));
console.log(numberToWord.getSentence(5.5));
console.log(numberToWord.getSentence());
There are a few things I found amiss in your code:
You don't need a class. You simply want to convert a number to a sentence. Use a function.
Why are both getSentence and convertSentence public? Only getSentence should be public.
Since your class will (in all probability) only be instatiated once, use the singleton pattern.
Things I would do:
Because you want to make your code modular, I would use the module pattern.
You can delegate specific tasks to different functions, but keep them in a private namespace.
Here's the code:
Number.prototype.toWord = function () {
return function (lang) {
var number = this.valueOf();
if (parseInt(number) === number) {
if (number < 10000 && number > 10000) {
switch (lang) {
case "es":
return toSpanish(number);
case "en":
default:
return toEnglish(number);
}
} else throw new RangeError("Expected an integer between ±10000.");
} else throw new TypeError("Expected an integer.");
};
function toSpanish(number) {
// convert the number to Spanish
}
function toEnglish(number) {
// convert the number to English
}
}();
Then you can use it like this:
var number = 1337;
alert(number.toWord("es"));
Edit: I wrote a simple function which will do what you want. However it's in English. I don't know Spanish so you'll have to implement that yourself. Here's the demo: http://jsfiddle.net/XKYhx/2/
My thinking would be to check how many parts you are going to have to the sentence and build an array to match with the substrings. for example, in English anyway (I don't speak Spanish!)
as natural language you would say (minus) xxx thousand and xxx
since your number has a max / min of ~10000 / ~-10000,
in pseudocode:
var sign = ""
var wholeparts = new Array()
var mantissaparts = new Array()
if number < 0,
sign = "minus"
number = math.abs(number) // turn the number into a positive number now we have the sign
var whole = math.floor(number) //get whole number
var mantissa = number - whole //get the after decimal part if exists
if whole > 1000
wholeparts.push(math.floor(whole/1000)) //get the thousands part
wholeparts.push(whole - parts[0]*1000) // add the hundreds
else
parts.push(whole)
if mantissa.length > 0
do something similar for the mantissa to the mantissaparts array.
At this point you would have the sentence structure broken down then:
string sentance:
foreach (var part in wholeparts)
stringify and check each number, converting to human words depending on index, ie "seven" or "seventy", add each to the string.
if wholeparts.length > 1 : sentence = sentence + " thousand and"
then if you had a mantissa, sentence = sentence + "point" .. then and the mantissa as natural language.
Best breakdown I can think of would be:
method to convert a number (whole or mantissa) to an array,
method to convert the array to natural language, with a parameter saying if it is whole or mantissa for the different wording that would be used.
method that accepts a number in string form and returns the natural language equivalent
Hope that helps .. was thinking on the fly.

Categories