Javascript condense if statement - javascript

I have an if statement in javascript that is
if(prop < 0 || trans < 0 || queue < 0 || proc < 0
|| prop > 1 || trans > 1 || queue > 1 || proc > 1
|| prop == "" || trans == "" || queue == "" || proc == ""){
Is there a way to condense this? For prop, trans, queue, and proc. I want to create an if statement if the values do not fall to be between 0 and 1 or if it has an empty string value

Building off of Jordan's answer:
var checkThese = [prop, trans, queue, proc];
var result = checkTruthinessOf(checkThese);
function checkTruthinessOf(things) {
return things.every(function(el) {
return (el < 0 || el > 1 || el === "");
});
}
See Array.prototype.every()

var checkThese = [prop, trans, queue, proc];
var result = checkTruthinessOf(checkThese);
function checkTruthinessOf(things) {
var returnValue = false;
[].forEach.call(things, function(thing){
if (thing < 0 || thing > 1 || thing == "") returnValue = true;
});
return returnValue;
};

I picked up this practice from jQuery. It eliminates the extra array and just passes in as many arguments as you like. Then use rink's function to validate all it at once.
var result = checkTruthinessOf(prop, trans, queue, proc);
function checkTruthinessOf(/*unlimited arguments*/) {
return Array.prototype.every.call(arguments, function(thing) {
return (thing < 0 || thing > 1 || thing === "");
});
}

Related

How to implement this test on prototype of String object?

How to implement this valid function?
I want to implement a test function that returns true or false,
example : 'any-string-1'.valid('!empty'):
this is my valid.js file
function valid(str) {
if (
typeof str == "undefined" ||
!str ||
str === "" ||
str.length < 10 ||
!/[^\s]/.test(str) ||
/^.*-s/i.test(str)
) {
return true;
} else if (str.length > 30) {
return false;
}
}
module.exports = valid;
Assuming you are using Jest, you can use toBe:
const emptyStr = '';
const str = 'some-str';
expect(Boolean(emptyStr.length)).toBe(false); // it's empty, it's false because length is 0;
expect(str.length > 30).toBe(false); // it's false because length is not greather than 30;
expect(str.length < 10).toBe(true); // it's true because length is lower than 10;

Cannot read property length null error when used with regular expressions

I'm a javascript beginner doing some CodeWars.com questions. I came across this question and I'm stuck due to a "cannot read property length null" error. I've tried to look up that error and can't find what the problem is in my program.
The assignment is:
"Check to see if a string has the same amount of 'x's and 'o's. The method must return a boolean and be case insensitive. The string can contains any char."
And this is what I've written so far:
function XO(str) {
var x = "x";
var o = "o";
var numX = str.match(/x/gi).length;
var numO = str.match(/o/gi).length;
while(str.indexOf(x) > -1 || str.indexOf(o) > -1) {
if(numX == numO){
return true;
}
}
if (numX === -1 && numO === -1){
return true;
}
}
XO("xoxo");
The assignment also says that if there is neither an X or an O then the program should return true.
This will not give you that error. When there are no matches, the match function returns null and you cannot get the length of null. A few extra lines solves this issue.
function XO(str) {
var x = "x";
var o = "o";
var numX = 0;
var numO = 0;
var xMatch = str.match(/x/gi);
var oMatch = str.match(/o/gi);
if (xMatch) {
numX = xMatch.length;
}
if (oMatch) {
numO = oMatch.length;
}
while(str.indexOf(x) > -1 || str.indexOf(o) > -1) {
if(numX == numO){
return true;
} else {
return false;
}
}
if (numX === -1 && numO === -1){
return true;
} else {
return false;
}
}
console.log(XO("ddd"));
I think you are making this problem more complex than it has to be.
All you need to do is make the string lowercase(to account for case insensitive), traverse the string, and when it finds an x, add 1 to a counter, and when you find and o, decrease 1 from the counter.
If it ends at 0, you return true, else you return false. There's no need for regexes
function XO(str){
var count = 0;
str = str.toLowerCase();
for(var i = 0; i < str.length; i++){
if(str[i] === 'x') count++;
if(str[i] === 'o') count--;
}
return count === 0 ? true : false;
}
Yes you have to check the return value of match is not null before checking the length property. However
while(str.indexOf(x) > -1 || str.indexOf(o) > -1) {
if(numX == numO){
return true;
}
}
looks like an infinite loop if either string contains lower case 'x' or 'o' and there are a different number of each.
More simply:
function XO(str)
{ var matchX = str.match(/x/gi);
var matchY = str.match(/o/gi);
return (matchX && matchY) ? matchX.length == matchY.length : !matchX && !matchY;
}

Javascript function to validate contents of an array

Here's what is asked:
validItems(items) – this function receives a string array of items which are to be for a customer. The function returns an empty string indicating all item codes in the array are valid; otherwise the function returns the first invalid item code in the array. All item codes must be selected from the item codes provided. They are: IT00, O144, 6A1L, 4243, O3D5, 44SG, CE64, 54FS and 4422.
This is what I've done so far:
function validItems(items) {
var error = false;
for (i = 0; i < items.length; i++) {
if (error == false) {
if (items[i] != "IT00" ||
items[i] != "0144" ||
items[i] != "6A1L" ||
items[i] != "4243" ||
items[i] != "O3D5" ||
items[i] != "44SG" ||
items[i] != "CE64" ||
items[i] != "54FS" ||
items[i] != "4422") {
error = items[i];
} else {
error = false;
}
} else {
if (error != false) {return error;} else {return "";}
}
}
}
var items = ["IT00","0144","6A1L"];
alert(validItems(items));
It keeps on returning IT00. What am I doing wrong?
What you'll notice here is that there is zero complexity. Each function below takes a couple arguments and does one simple task. It's very easy to see what each function does at first glance.
// your data
const validItems = [
"0144", "6A1L", "4243", "O3D5", "44SG", "CE64", "54FS", "4422"
];
// some reusable functions
const all = f => xs => xs.every(f);
const comp = f => g => x => f(g(x));
const neq = y => x => x !== y;
const indexOf = xs => x => xs.indexOf(x);
const elem = xs => comp(neq(-1))(indexOf(xs))
// your helpers
const validateItems = all(elem(validItems));
// test it out
console.log( validateItems(["0144", "6A1L"]) ); // true
console.log( validateItems(["0144", "CAKE"]) ); // false
You can use a simple array based test like
var validCodes = ['IT00', 'O144', '6A1L', '4243', 'O3D5', '44SG', 'CE64', '54FS', '4422'];
function validItems(items) {
for (var i = 0; i < items.length; i++) {
if (validCodes.indexOf(items[i]) == -1) {
return items[i];
}
}
return '';
}
var items = ["IT00", "O144", "6A1L"];
alert(validItems(items));
To make your code work
function validItems(items) {
var error = false;
for (i = 0; i < items.length; i++) {
console.log(items[i], error)
if (error == false) {
//need to use && since otherwise one value cann't satisfy all these conidtions
if (items[i] != "IT00" && items[i] != "0144" && items[i] != "6A1L" && items[i] != "4243" && items[i] != "O3D5" && items[i] != "44SG" && items[i] != "CE64" && items[i] != "54FS" && items[i] != "4422") {
//if current item is not matching assign it to the error and break the loop
error = items[i];
break;
//you can really return from here, not need to use the error variable also
}
}
}
//this should be outside of the loop
//if there is an errro return the error string
if (error != false) {
return error;
} else {
return "";
}
return '';
}
var items = ["IT00", "0144", "6A1L"];
alert(validItems(items));
According to your code it is correct that it is outputting IT00.
You are using the OR selector which means if the string is IT00, then it is not 0144 or 6A1L. Your intention is to exclude ALL so you are looking for values which are not IT00 AND not 0144 ANd not 6A1L, etc. etc.
use the AND:
if (items[i] != "IT00" &&
items[i] != "0144" &&
items[i] != "6A1L" &&
items[i] != "4243" &&
items[i] != "O3D5" &&
items[i] != "44SG" &&
items[i] != "CE64" &&
items[i] != "54FS" &&
items[i] != "4422") {
When you understand the basic of this logic, also try to rewrite your code. An array of allowed values is for example a bit more tidy ;-)
Your first item returns true on your if statement. If your first item is "ITOO", The first match of you make is:
items[i] != "0144"
your code then says
error = items[i]; //which is "ITOO"
and then you return
error
which is the first item "ITOO"
Your Or condition should have "==" instead of "!=".
Which means -> If "the give code" is same as "any of the recognized codes" then recognize it otherwise drop it.
Currently your condition means -> If "the given code" is not same as "any of the recognized code" then recognize it. This condition will always be true
You had some basic coding errors in your code.
I've modified your code and put in the comments where I saw room for improvement.
Basically your if else statements were redundant. If you simply exit the function by returning the faulty thing you already get the desired result.
No need to keep looping if we have found a mismatch.
In a function where you'd need to do additional checks after finding a fault you would use break and then do your logic on error if error !== false
function validItems(items) {
// create a valid items array. This will make maintaining valid item codes easier. and keep your code readable.
var valid = ["IT00","0144","6A1L","4243","O3D5","44SG","CE64","54FS","4422"];
var error = false;
for (i = 0; i < items.length; i++) {
// Type safe test. Always use 3 === isntead of == your test would have returned true on eveyrthing.
if (error === false) {
if(valid.indexOf(items[i]) === -1) {
// immedeately escape
return items[i];
} /*else {// Totally uneccesary
error = false;
}
} else {
// not needed here. this also escaped your loop after first iteration.
if (error !== false) {return error;} else {return "";}
}*/
}
// we return here because we know the loop is done then.
return error;
}
var items = ["IT00","0144","6A1L"];
alert(validItems(items));

Sort empty or null to bottom always

The following is a natural sort function I pulled from somewhere I forget exactly. I'm looking to modify it so that empty or null values always sort to the bottom regardless of asc/desc.
Here is what I have right now:
function gridNaturalSorter(a, b) {
if(a[sortcol])
a = a[sortcol].replace(/<(?:.|\n)*?>/gm, '');
if(b[sortcol])
b = b[sortcol].replace(/<(?:.|\n)*?>/gm, '');
if(b)
b = b.toString().substr(0, 15);
if(a)
a = a.toString().substr(0, 15);
var re = /(^([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/gi,
sre = /(^[ ]*|[ ]*$)/g,
dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
hre = /^0x[0-9a-f]+$/i,
ore = /^0/,
i = function(s) {
return gridNaturalSorter.insensitive && (''+s).toLowerCase() || ''+s
},
// convert all to strings strip whitespace
x = i(a).replace(sre, '') || '',
y = i(b).replace(sre, '') || '',
// chunk/tokenize
xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
// numeric, hex or date detection
xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x)),
yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null,
oFxNcL, oFyNcL;
// first try and sort Hex codes or Dates
if (yD)
if ( xD < yD ) return -1;
else if ( xD > yD ) return 1;
// natural sorting through split numeric strings and default strings
for(var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
// find floats not starting with '0', string or 0 if not defined (Clint Priest)
oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
// handle numeric vs string comparison - number < string - (Kyle Adams)
if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {
return (isNaN(oFxNcL)) ? 1 : -1;
}
// rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
else if (typeof oFxNcL !== typeof oFyNcL) {
oFxNcL += '';
oFyNcL += '';
}
if (oFxNcL < oFyNcL)
return -1;
if (oFxNcL > oFyNcL)
return 1;
}
return 0;
}
If you know how to implement multiple comparators and a comparator that sorts null to bottom that's quite easy.
To implement multiple comparators, you just have to return the result of the first comparator that doesn't return 0.
Here I also created a withComparators helper function that allows to compose multiple comparators together. If you understand this code you will be able to easily come up with your own solution for your specific problem.
Note that your gridNaturalSorter function is a comparator just like nullsToBottom is in my example.
E.g.
var items = ['test', null, 'test1', 'test3', null, 'test4'];
items.sort(withComparators(nullsToBottom, textAsc));
//["test", "test1", "test3", "test4", null, null]
function nullsToBottom(a, b) {
return a === b? 0 : a === null? 1 : -1;
}
function textAsc(a, b) {
return a < b? -1 : +(a > b);
}
function withComparators() {
var comparators = arguments;
return function (a, b) {
var len = comparators.length, i = 0, result;
for (; i < len; i++) {
result = comparators[i](a, b);
if (result) return result;
}
return 0;
};
}

Javascript If statement, looking through an array

Mind has gone blank this afternoon and can't for the life of me figure out the right way to do this:
if(i!="3" && i!="4" && i!="5" && i!="6" && i!="7" && i!="8" && i!="9" && i!="2" && i!="19" && i!="18" && i!="60" && i!="61" && i!="50" && i!="49" && i!="79" && i!="78" && i!="81" && i!="82" && i!="80" && i!="70" && i!="90" && i!="91" && i!="92" && i!="93" && i!="94"){
//do stuff
}
All those numbers need to be in an array, then I can check to see if "i" is not equal to any 1 of them.
var a = [3,4,5,6,7,8,9];
if ( a.indexOf( 2 ) == -1 ) {
// do stuff
}
indexOf returns -1 if the number is not found. It returns something other than -1 if it is found. Change your logic if you want.
Wrap the numbers in quotes if you need strings ( a = ['1','2'] ). I don't know what you're dealing with so I made them numbers.
IE and other obscure/older browsers will need the indexOf method:
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(elt /*, from*/)
{
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++)
{
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
}
My mind made this solution:
function not(dat, arr) { //"not" function
for(var i=0;i<arr.length;i++) {
if(arr[i] == dat){return false;}
}
return true;
}
var check = [2,3,4,5,6,7,8,9,18,19,49,50,60,61,70,78,79,80,81,82,90,91,92,93,94]; //numbers
if(not(i, check)) {
//do stuff
}
This solution is cross-browser:
var valid = true;
var cantbe = [3, 4, 5]; // Fill in all your values
for (var j in cantbe)
if (typeof cantbe[j] === "number" && i == cantbe[j]){
valid = false;
break;
}
valid will be true if i isn't a 'bad' value, false otherwise.

Categories

Resources