some() function is not working with && operator - javascript

I´m triying to use the some() function with && operator, but always return false, even if both conditions are inside in the array.
For example:
if (acciones.some(a => a.accionID == 7 && a.accionID == 8)) {
return true;
} else {
return false;
}

You're checking one specific accionID on each call to the some callback. That one accionID cannot be both == 7 and == 8 at the same time. Any given accionID will be 7 or 8.
If you want to see if all of the acciones have accionID of 7 or 8, use every with ||:
if (acciones.every(a => a.accionID == 7 || a.accionID == 8)) {
// ----------^--------------------------^
If you want to see if any of the acciones has an accionID of 7 or 8, use some with ||:
if (acciones.some(a => a.accionID == 7 || a.accionID == 8)) {
// ----------^-------------------------^
If acciones has at least one entry in it where accionID is (say) 6, the every check will be false, and the some check will be true.
Since some and every already return a boolean, there's no need for:
if (acciones.every(a => a.accionID == 7 || a.accionID == 8)) {
return true;
} else {
return false;
}
Just use
return acciones.every(a => a.accionID == 7 || a.accionID == 8);
In general, if you find yourself writing:
if (x) {
return true;
} else {
return false;
}
then:
If x is already a boolean, you can do just
return x;
If x is not necessarily boolean (and it matters that you return a boolean, specifically), you can use the !! idiom to make it a boolean:
return !!x;
Similarly, if you find yourself writing:
if (x) {
return false;
} else {
return true;
}
you can always write that as
return !x;
instead.

Related

My function returns the catch all when i'm passing a string that fits the parameters I've tried to set. How to proceed?

I’m running into a wall on the second step of this project. My console test returns as “Card number not recognized” when I put in a Visa or MasterCard number, and the intent is for it to detect which network the card number is from. Any insight you could afford me would be greatly appreciated.
var detectNetwork = function(cardNumber) {
// Note: `cardNumber` will always be a string
var splt = cardNumber.split('');
// The Diner's Club network always starts with a 38 or 39 and is 14 digits long
if ((splt[0] === '3') && (splt[1] === '8' || splt[1] === '9') && (splt.length === 14)) {
return 'Diner\'s Club';
} else if ((splt[0] === '3') && (splt[1] === '4' || splt[1] === '7') && (splt.length === 15)) {
return 'American Express';
} else if ((splt[0] === '4') &&
(splt.length === 13 ||
splt.length === 16 ||
splt.length === 19)) {
return 'Visa';
} else if ((splt[0] === '5') &&
((splt[1] === '1') || (splt[1] === '2') || (splt[1] === '3') ||
(splt[1] === '4') || (splt[1] === '5')) &&
(splt.length === 16)) {
return 'MasterCard';
} else {
return 'Card number not recognized';
}
// The American Express network always starts with a 34 or 37 and is 15 digits long
// Once you've read this, go ahead and try to implement this function, then return to the console.
};
instead of using a bunch of IFs, I would rather to use RegExp so it is easier to follow what you want to achieve.
Additionally to that, before checking the string I also recommend to clean it, so in case you get something like:
1234-1234.1234 1234$1234
it will cleaned and you will get something like:
12341234123412341234
and it is easier to check if it really matches
here you have all my recommendations applied and working, I put an example of each of the cases, along with this you can see that the first 1/2 digits are separated, so you can recognize it better.
const replacer = /[^\d]/g;
const dinnersRegex = /^3(8|9)\d{12}$/;
const americanRegex = /^3(4|7)\d{13}$/;
const visaRegex = /^4(\d{18}|\d{15}|\d{12})$/;
const masterRegex = /^5(1|2|3|4|5)\d{14}$/;
var detectNetwork = function(cardNumber) {
// lets replace all weird characters BUT numbers.
const cleanNumber = cardNumber.replace(replacer, "")
if (dinnersRegex.test(cleanNumber)) {
return 'Diner\'s Club';
} else if (americanRegex.test(cleanNumber)) {
return 'American Express';
} else if (visaRegex.test(cleanNumber)) {
return 'Visa';
} else if (masterRegex.test(cleanNumber)) {
return 'MasterCard';
} else {
return 'Card number not recognized';
}
};
// used some weird symbols to use the cleaner and see if it works.
console.log("diners1:", detectNetwork("38--12-1231-1234-12"))
console.log("diners2:", detectNetwork("39--12-1231-1234-12"))
console.log("american1:", detectNetwork("34 121231 1234 129"))
console.log("american2:", detectNetwork("37 121231 1234 129"))
console.log("visa1:", detectNetwork("4 712.1231.1234.1291.123"))
console.log("visa2:", detectNetwork("4 712123112341298"))
console.log("visa3:", detectNetwork("4 712123112341"))
console.log("master1:", detectNetwork("5 112123112341291"))
console.log("master1:", detectNetwork("5 212123112341291"))
console.log("master1:", detectNetwork("5 312123112341291"))
console.log("master1:", detectNetwork("5 412123112341291"))
console.log("master1:", detectNetwork("5 512123112341291"))
console.log("unrecognized:", detectNetwork("9812311234129"))

How to check null and implement logic based on that in JS?

I have parseNotAvailable function that based on version have some logic, so i have penalties that has coming as version 2 but i need to have logic same as version 1, So i tried to pass as null to get 0 but its not working and throwing error.
Any better approach to achieve above task ?
main.js
let newPrice = {
copayEmployer: parseNotAvailable('N/A', 1),
penalties: parseNotAvailable('N/A', null),
secondaryClaimNumber: parseNotAvailable('N/A',2)
};
function parseNotAvailable(value, version) {
if ((value === 'N/A' || value === 'n/a') && (version || version === 1)) {
return 0;
} else if ((value === 'N/A' || value === 'n/a') && version === 2) {
return null;
} else {
return parseFloat(value);
}
};
// console.log(parseNotAvailable('N/A', 1));
console.log(newPrice);
expected Result
{ copayEmployer: 0, penalties: 0, secondaryClaimNumber: null }
with above code its returning
{ copayEmployer: 0, penalties: NaN, secondaryClaimNumber: 0 }
In parseNotAvailable('N/A', null) version is null and does not pass if statements na goes to else statement return parseFloat(value);
In parseNotAvailable('N/A', 2) version is 2 and it pass first if statements... ||(value || value === 1) and return 0;
You have wrong assertion if ((value === 'N/A' || value === 'n/a') && (version || version === 1)) it should be if ((value === 'N/A' || value === 'n/a') && (!version || version === 1))
You're code is flowing to the else block and trying attempting to parseInt('N/A'), which obviously is NaN. You may want to rethink your conditions there. I added a simple isNaN check to your code as you can see:
try {
let newPrice = {
copayEmployer: parseNotAvailable('N/A', 1),
penalties: parseNotAvailable('N/A', null),
secondaryClaimNumber: parseNotAvailable('N/A', 2)
};
console.log(newPrice);
} catch (err) {
console.error(err)
}
function parseNotAvailable(value, version) {
if ((value === 'N/A' || value === 'n/a') && (version || version === 1)) {
return 0;
} else if ((value === 'N/A' || value === 'n/a') && version === 2) {
return null;
} else {
//Do a check here for NaN value - this probably isnt needed if you straigten out your flow control conditions
if (isNaN(value)) {
throw `${value} is NaN`;
}
return parseFloat(value);
}
};

Simple PIN validation

Task:
ATM machines allow 4 or 6 digit PIN codes and PIN codes cannot contain anything but exactly 4 digits or exactly 6 digits.
If the function is passed a valid PIN string, return true, else return false.
My solution:
function validatePIN (pin) {
//return true or false
if (!isNaN(pin) && Number.isInteger(pin) && pin.toString().length == 4 || pin.toString().length == 6) {
return true
} else {
return false
}
}
The only bug I get is when I pass 4 digits as a string ("1234") - it equals false.
function validatePIN (pin) {
return typeof pin === 'string' && // verify that the pin is a string
Number.isInteger(+pin) && // make sure that the string is an integer when converted into a number
[4, 6].includes(pin.length) // only accepts 4 and 6 character pins
}
function validatePIN(pin) {
var isNumber = /^\d+$/.test(pin) && (pin.length == 4 || pin.length == 6)
return isNumber
}
validatePIN('0193')
//returns true
You can use Array.prototype.every(), Array.prototype.some(), String.prototype.match()
<input type="text" />
<button>validate pin</button>
<script>
var validatePIN = (args) => {[...args] = args;
return args.every(v => v.match(/\d/)) &&
[4, 6].some(n => args.length === n)};
document.querySelector("button")
.addEventListener("click", (e) =>
alert(validatePIN(e.target.previousElementSibling.value))
)
</script>
function validatePIN (pin) {
//return true or false
return /^\d+$/.test(pin) && (pin.length === 4 || pin.length === 6)
}
function validatePIN (pin) {
if (pin.length !== 4 && pin.length !== 6) {
return false;
}
for (let i = 0; i < pin.length; i++) {
if (pin[i] > '9' || pin[i] < '0') {
return false;
}
}
return true;
}
Here is another way to solve using regular expression.
function validatePIN(pin) {
return /^(\d{4}|\d{6})$/.test(pin)
}
validatePIN('2345')
//returns true
validatePIN('2.45')
//reutrns false
function validatePIN (pin) {
if (pin.length == 4 || pin.length == 6)
{
for (let i = 0; i < pin.length; i++)
{
if (pin[i] == "0" ||
pin[i] == "1" ||
pin[i] == "2" ||
pin[i] == "3" ||
pin[i] == "4" ||
pin[i] == "5" ||
pin[i] == "6" ||
pin[i] == "7" ||
pin[i] == "8" ||
pin[i] == "9") ;
else return false;
}
return true;
}
else return false;
}
this code checks the PIN-length and passes all test tasks with numbers and not numbers...
public static boolean validatePin(String pin) {
return pin.matches("\\d{4}|\\d{6}");
}

Multiple conditions in if statement on both sides of the logical operator

I was experimenting with having multiple arguments in an if statement on both sides of the logical operator. I first started with the || operator, which worked as expected:
var a = 'apple', b = 'banana', c = 'cherry';
if (a == 'banana' || a == 'apple' || b == 'banana' || b == 'apple') {
console.log('example 1') // returns
}
if ((a || b) == 'banana' || (a || b) == 'apple') {
console.log('example 2') // returns
}
if (a == ('apple' || 'banana') || b == ('apple' || 'banana')) {
console.log('example 3') // returns
}
if ((a || b) == ('apple' || 'banana')) {
console.log('example 4') // returns
}
So far, no unexpected results.
However, when following a similar structure when replacing the || operator for the && operator, things don't quite work as I expect them to.
if ((a == 'banana' && b == 'apple') || (a == 'apple' && b == 'banana')) {
console.log('example 5') // returns
}
if (((a || b) == 'banana') && ((a || b) == 'apple')) {
console.log('example 6') // DOESN'T RETURN
}
if ((a || b) == 'banana') {
console.log('example 6a') // DOESN'T RETURN - consistent with example 6
}
if ((a == ('apple' || 'banana')) && (b == ('apple' || 'banana'))) {
console.log('example 7') // DOESN'T RETURN
}
if (a == ('apple' || 'banana')) {
console.log('example 7a') // returns - inconsistent with example 7
}
if (b == ('apple' || 'banana')) {
console.log('example 7b') // DOESN'T RETURN - inconsistent with example 7a
}
if ((a && b) == ('apple' || 'banana')) {
console.log('example 8') // DOESN'T RETURN
}
if ('apple' == (a || b) && 'banana' == (a || b)) {
console.log('example 9') // DOESN'T RETURN
}
Now, I am wondering: is there a flaw in my logic or can it just not be done this way? My aim is to write these if statements as short as possible, for the purpose of readibility and maintainability. Clearly I am just exploring possibilities.
Does anyone know any way to go about this? Especially example 7/7a/7b seems peculiar to me because it yields inconsistent results despite a similar structure [Fiddle]
The Logical OR operator doesn't work in a way you're looking for.
Returns expr1 if it can be converted to true; otherwise, returns expr2. Thus, when used with Boolean values, || returns true if either operand is true; if both are false, returns false.
MDN
One alternative way could be make use of array's indexOf method. Just be aware it will return the index of the array element, so 0 could be a valid value also. In order to make our if statement works as expected, we have to use 0 <= ... like this:
if ( 0 <= ["apple","banana"].indexOf(a) ) { ... }
The other thing you can do is using in operator. Also as it checks only against the keys, you can leave the values empty like this:
if ( a in { "apple": "", "banana": "" } ) { ... }
If you have lot's of options, obviously it's better to do the following:
var options = {
"apple": "",
"banana": ""
}
if ( a in options ) { ... }
Personally I think with just two options to check, this will be more readable for a human-eye to go for two separated checks, and I think in your examples you don't really need to shorten the if statements as they're already quite short and readable in my opinion.
if ( "apple" === a || "banana" === a ) { ... }
If you want a clean way to check if a variable equals any of a number of other variables, try using a function like this:
http://jsfiddle.net/aYRmL/
function equalsAny (first) {
return !![].slice.call(arguments, 1).filter(function (val) {
return first === val;
}).length;
}
The first argument is the one being compared to the rest. Use it like this:
var a = 'banana', b = 'orange';
equalsAny(a, 'banana', 'apple'); // returns true
equalsAny('orange', a, b); // returns true
The first one above accomplishes what you were trying to do with a == ('banana' || 'apple'). The seconds accomplishes what you were trying to do with (a || b) == 'banana'.
As an alternative solution you can use some or every:
var __slice = [].slice;
function any(a) {
return __slice.call(arguments,1).some(function(x) {
return a === x;
});
}
function all(a) {
return __slice.call(arguments,1).every(function(x) {
return a === x;
});
}
And use like:
// Instead of:
// if (a == 'banana' || a == 'apple' || a == 'orange')
if (any(a, 'banana', 'apple', 'orange')) {
...
}
// Instead of:
// if (a == 'banana' && b == 'banana' && c == 'banana')
if (all('banana', a, b, c)) {
...
}
(a || b) == 'banana' always will be false because (a || b) will return a Boolean witch is not equal to a string
UPDATE :
did some testing (a || b) always returns the first operand (a in this case) witch is 'apple' and not equal to 'banana'.
|| and && will give excepted result only if the both operands are Boolean or can be cased to Boolean.
The way it's working is that a && b and a || b are always set to the value of one of the variables. a && b will always be set to the value of b unless a is false, in which case the answer must be false. Similarly a || b will be set to the value of a, unless a is false, in which case it will be set to the value of b. As elclanrs mentioned, this is because of short-circuit evaluation -- the first operand may determine the result, in which case there's no point in looking at the second operand.
When both a and b are strings, they will never be false unless the string is zero-length. So a || b will be 'apple' in your case, and a && b will be 'banana'.

Javascript if clause not working properly

I have the following Javascript/jQuery:
$('#List').keypress(function (e) {
if (e.which == 13) {
var lines = $('#List').val().split('\n');
mylast = lines[lines.length - 1];
mylen = mylast.length;
if ((mylen != 8) || (mylen != 4)) {
lines = lines.slice(lines.length-1);
$('#List').val(lines.join("\n"));
alert(mylen);
return false;
}
return true;
}
});
But it jumps into the code block after if even if length is 4 or 8....
Where is my error?
I want to remove the last line of the textarea if it's not of a given length.
It should not be:
if ((mylen != 8) || (mylen != 4)) {
it should be:
if ((mylen != 8) && (mylen != 4)) {
your way if it was 8 , it was not 4 so it was getting through or if it was 4 it was not 8. you need to check that its not either
This line:
if ((mylen != 8) || (mylen != 4)) {
means "if length is not 8 or length is not 4". So for instance, 4 is not 8, so the condition is true (the second part is never tested, because JavaScript expressions are short-circuited). Similarly, if it's 8, the first part of the expression is false, but the second part (8 != 4) is true, and so the expression is true.
You probably want:
if ((mylen != 8) && (mylen != 4)) {
&& means "and."
Lets examine the case of when mylen is 4.
mylen != 8 //true
mylen != 4 //false
true || false // true
What you probably want is to prevent mylen from being 8 and prevent mylen from being 4:
(mylen != 8) && (mylen != 4)
FWIW, here's a better version of your code:
$('#List').keypress(function (e) {
var lines, last, valid;
if (e.which === 13) {
lines = $(this).val().split('\n');
last = lines.pop();
valid = last.length === 4 || last.length === 8;
if (!valid) {
$(this).val(lines.join("\n"));
e.preventDefault();
}
}
});
it declares all variables as local (never forget the var keyword!)
it uses $(this) instead of repeating the $('#List')
it uses e.preventDefault() instead of returning false
it uses a variable named valid to transport meaning clearer
it uses strict comparison (===)
if the code is part of a form validity check, consider putting it into the submit event handler instead of capturing the Enter key.

Categories

Resources