Javascript - checking whether a condition met in Array forEach - javascript

var myStringArray = ["abcd", "efgh", "ijkl"], foundResult = false;
myStringArray.forEach(function(currentString) {
if (/\d+/.test(currentString)) {
console.log("Number found");
foundResult = true;
}
});
if(foundResult === false) {
console.log("Number NOT found");
}
This piece of code is to demonstrate the problem. I have to use an extra variable to check whether there was a match or not. Is there any elegant way to handle this without the variable?
Edit: I know I can use some, but I would like to match the no match case as well as seen in the code's last if condition.

Use some method:
if(["abcd", "efgh", "ijkl"].some(function(i){return /\d+/.test(i)})){
// if matched
} else {
// handle no match
}

An alternative that uses forEach is:
var a = ['abcd', 'efgh', 'ijkl'];
var r;
if (a.forEach(function(a){r = r || /\d/.test(a)}) || r) {
alert('found a number');
} else if (r === false) {
alert('no numbers');
}
but likely any UA that supports forEach will also support some, and some is also probably more efficient as it will stop at the first result of true.

Related

Use function return as the content for a conditional statement

i'd like to use the return value of a specific function as the condition of an if statement. Is that possible ?
I'm basically building a string inside a function that takes an array (the conditionArray) and concatenates it to a statement.
Then it returns this condition as a string.
After that, i wanted to use this string as the condition of my if-statement.
My current problem looks something like that.
var answer = prompt("Tell me the name of a typical domestic animal");
var conditionArray = new Array("Dog", "Turtle", "Cat", "Mouse")
function getCondition(conditionArray) {
for (i = 0; i < conditionArray.length; i++) {
if (i != conditionArray.length) {
condition += 'answer === ' + conditionArray[i] + ' || ';
} else {
condition += 'answer === ' + conditionArray[i];
}
return condition;
}
}
if (getCondition(conditionArray)) {
alert("That is correct !");
} else {
alert("That is not a domestic animal !");
}
For this type of test use Array.prototype.indexOf, x = arr.indexOf(item)
x === -1 means item is not in arr
Otherwise x is the index of arr that the first occurrence of item is located
var options = ["Dog", "Turtle", "Cat", "Mouse"],
answer = prompt("Tell me the name of a typical domestic animal");
// some transformation of `answer` here, i.e. casing etc
if (options.indexOf(answer) !== -1) {
alert("That is correct !");
} else {
alert("That is not a domestic animal !");
}
The best way to do this kind of test is to use Array.prototype.indexOf. See Paul's answer for more details on how to use it.
--
If you really really want to return a condition, you can use eval() to evaluate the condition string. Keep in mind that eval() is dangerous though. It's usage isn't recommended. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Don%27t_use_eval_needlessly!
if (eval(getCondition(conditionArray))) {
alert("That is correct !");
} else {
alert("That is not a domestic animal !");
}

If Else Conditionals within Function in JavaScript

I'm having issues with conditionals. I want to return the index where pattern starts in string (or -1 if not found). The search is to be case sensitive if the 3rd parameter is true otherwise it is case insensitive.
Examples
index("abAB12","AB",true) returns 2 but index("abAB12","AB",false) returns 0
index("abAB12","BA",true) returns -1 and index("abAB12","BA",false) returns 1
Any idea how I can accomplish this?
This is my code so far
var s = "abAB12"
var p = "AB"
var cs = true
function index(string, pattern, caseSensitive) {
if (pattern) {
var found = false;
if (caseSensitive = false) {
if (string.indexOf(pattern.) >= 0) {
found = true;
}
return (found);
else {
return ("");
}
} else if (caseSensitive = true) {
if (string.toLowerCase().indexOf(pattern.toLowerCase()) >= 0) {
found = true;
}
return (found);
} else {
return ("");
}
}
}
alert(index(s, p, cs));
Fiddle at http://jsfiddle.net/AfDFb/1/
You have some mistype in your code. On the 15th line you have
}
return (found);
else {
This is not not valid. Change it to
return (found);
}
else {
There is another one.
if (caseSensitive = false) {
= used for assignment. You need to use == in if statements when comparing.
Also on the 13th line, there's an extra . after pattern. Remove it.
if (string.indexOf(pattern.) >= 0) {
Your fiddle example
You can use string.search() with a regular expression to accomplish this in one liner:
function index(input, key, caseMatters) {
return input.search(new RegExp(key, caseMatters ? '' : 'i'));
}
Now you can:
index("abAB12","AB",true); // returns 2
index("abAB12","AB",false); // returns 0
index("abAB12","BA",true); // returns -1
index("abAB12","BA",false); // returns 1
You need to use double equals sign == in your if, else statements.
if(caseSensitive == false)
And
if(caseSensitive == true)
You are assigning value inside if condition instead of comparing it.
Try
if (caseSensitive == false) {
and
if(caseSensitive == true)
You'd better use search :
'abAB12'.search(/AB/); // 2
'abAB12'.search(/AB/i); // 0
'abAB12'.search(/BA/); // -1
'abAB12'.search(/BA/i); // 1
The i flag means "case insensitive" ( insensible à la casse :D ).

Javascript if value is in array else in next array

I have found a few posts on here with similar questions but not entirely the same as what I am trying. I am currently using a simple if statement that checks the data the user enters then checks to see if it starts with a number of different values. I am doing this with the following:
var value = string;
var value = value.toLowerCase();
country = "NONE";
county = "NONE";
if (value.indexOf('ba1 ') == 0 || value.indexOf('ba2 ') == 0 || value.indexOf('ba3 ') == 0) { //CHECK AVON (MAINLAND UK) UK.AVON
country = "UK";
county = "UK.AVON";
} else if(value.indexOf('lu') == 0){//CHECK BEDFORDSHIRE (MAINLAND UK) UK.BEDS
country = "UK";
county = "UK.BEDS";
}
I have about 20-30 different if, else statements that are basically checking the post code entered and finding the county associated. However some of these if statements are incredibly long so I would like to store the values inside an array and then in the if statement simply check value.indexOf() for each of the array values.
So in the above example I would have an array as follows for the statement:
var avon = new Array('ba1 ','ba 2','ba3 ');
then inside the indexOf() use each value
Would this be possible with minimal script or am I going to need to make a function for this to work? I am ideally wanting to keep the array inside the if statement instead of querying for each array value.
You can use the some Array method (though you might need to shim it for legacy environments):
var value = string.toLowerCase(),
country = "NONE",
county = "NONE";
if (['ba1 ','ba 2','ba3 '].some(function(str) {
return value.slice(0, str.length) === str;
})) {
country = "UK";
county = "UK.AVON";
}
(using a more performant How to check if a string "StartsWith" another string? implementation also)
For an even shorter condition, you might also resort to regex (anchor and alternation):
if (/^ba(1 | 2|3 )/i.test(string)) { … }
No, it doesn’t exist, but you can make a function to do just that:
function containsAny(string, substrings) {
for(var i = 0; i < substrings.length; i++) {
if(string.indexOf(substrings[i]) !== -1) {
return true;
}
}
return false;
}
Alternatively, there’s a regular expression:
/ba[123] /.test(value)
My recomendation is to rethink your approach and use regular expressions instead of indexOf.
But if you really need it, you can use the following method:
function checkStart(value, acceptableStarts){
for (var i=0; i<acceptableStarts.length; i++) {
if (value.indexOf(acceptableStarts[i]) == 0) {
return true;
}
}
return false;
}
Your previous usage turns into:
if (checkStart(value, ['ba1', ba2 ', 'ba3'])) {
country = 'UK';
}
Even better you can generalize stuff, like this:
var countryPrefixes = {
'UK' : ['ba1','ba2 ', 'ba3'],
'FR' : ['fa2','fa2']
}
for (var key in countryPrefixes) {
if (checkStart(value, countryPrefixes[key]) {
country = key;
}
}
I'd forget using hard-coded logic for this, and just use data:
var countyMapping = {
'BA1': 'UK.AVON',
'BA2': 'UK.AVON',
'BA3': 'UK.AVON',
'LU': 'UK.BEDS',
...
};
Take successive characters off the right hand side of the postcode and do a trivial lookup in the table until you get a match. Four or so lines of code ought to do it:
function getCounty(str) {
while (str.length) {
var res = countyMapping[str];
if (res !== undefined) return res;
str = str.slice(0, -1);
}
}
I'd suggest normalising your strings first to ensure that the space between the two halves of the postcode is present and in the right place.
For extra bonus points, get the table out of a database so you don't have to modify your code when Scotland gets thrown out of leaves the UK ;-)

Including a for loop in an if statement

I'm building an application in which I want to display some errors when a user enters invalid values in an input box. A correct value is appended as 'entry' to a div if no errors were found. In total there are 3 cases when to display errors:
The input value is empty
The input value is a number
The input value already exists
These errors are displayed with if else statements.
1.and 2. were easy, but the problem case (3.) only validates against the first element of class .cat_entry.
if(cat_input == '') { // generate errors
errorDisplay(error_input_empty);
} else if(!isNaN(cat_input)) {
errorDisplay(error_input_number);
} else if($('.cat_entry') == cat_input) { // THIS IS THE PROBLEMATIC LINE
// .cat_entry is the class of the entries that have been appended
errorDisplay(error_duplicate);
} else {
// stuff
};
So I believe I need a for loop/ .each() (no problem so far), but how do I include this as a condition in an if statement? Something like.. if( for(i=0;i<$('.cat_entry').length;i++) { ... }; ... How to return true (or something similar) when one of the entries matches the input value, then pass the return value to the if statement?
EDIT: here is a jsFiddle with the relevant code. I updated it with $.inArray() method. I'd like to try and use this instead of a for / .each() loop.
You can try this:
var a=$('.cat_entry'),o={};
for(i=0;i<a.length;i++) {
var s=a[i].val();
if(s in o){
errorDisplay(error_duplicate);
return;
}
o[s]=true;
}
or
var o={};
$('.cat_entry').each(function(){
var s=$(this).val();
if(s in o){
errorDisplay(error_duplicate);
return;
}
o[s]=true;
}
You can actually use the jQuery inArray function for this, such as:
else if($.inArray(cat_input, $('.cat_entry') != -1)
}
The solution was to add this to the function:
var isDuplicate = false;
$('.cat_entry').each(function() {
if(!$(this).text().indexOf(cat_input)) {
isDuplicate = true;
}
// And in the if else loop:
else if(isDuplicate == true)
//and just before the function ends
isDuplicate = false;
Thanks to all for the help you offered.

Faster and shorter way to check if a cookie exists

What is the shorter and faster way to know if a cookie has a value or exists?
I'm using this to know if exists:
document.cookie.indexOf('COOKIENAME=')== -1
This to know if has a value
document.cookie.indexOf('COOKIENAME=VALUE')== -1
Any better? Any problems on this method?
I would suggest writing a little helper function to avoid what zzzzBov mentioned in the comment
The way you use indexOf, it would only evaluate correct if you check for the containment of a String in a cookie, it doesn't match a complete name, in that case the above would return false therefore giving you the wrong result.
function getCookie (name,value) {
if(document.cookie.indexOf(name) == 0) //Match without a ';' if its the firs
return -1<document.cookie.indexOf(value?name+"="+value+";":name+"=")
else if(value && document.cookie.indexOf("; "+name+"="+value) + name.length + value.length + 3== document.cookie.length) //match without an ending ';' if its the last
return true
else { //match cookies in the middle with 2 ';' if you want to check for a value
return -1<document.cookie.indexOf("; "+(value?name+"="+value + ";":name+"="))
}
}
getCookie("utmz") //false
getCookie("__utmz" ) //true
However, this seems to be a bit slow, so giving it an other approach with splitting them
Those are two other possibilities
function getCookie2 (name,value) {
var found = false;
document.cookie.split(";").forEach(function(e) {
var cookie = e.split("=");
if(name == cookie[0].trim() && (!value || value == cookie[1].trim())) {
found = true;
}
})
return found;
}
This one, using the native forEach loop and splitting the cookie array
function getCookie3 (name,value) {
var found = false;
var cookies = document.cookie.split(";");
for (var i = 0,ilen = cookies.length;i<ilen;i++) {
var cookie = cookies[i].split("=");
if(name == cookie[0].trim() && (!value || value == cookie[1].trim())) {
return found=true;
}
}
return found;
};
And this, using an old for loop, which has the advantage of being able to early return the for loop if a cookie is found
Taking a look on JSPerf the last 2 aren't even that slow and only return true if theres really a cookie with the name or value, respectively
I hope you understand what i mean
Apparently:
document.cookie.indexOf("COOKIENAME=VALUE");
For me, is faster, but only slightly.
As the test shows, surprisingly, it's even faster to split the cookie up into arrays first:
document.cookie.split(";").indexOf("COOKIENAME=VALUE");
I use Jquery cookie plugin for this.
<script type="text/javascript" src="jquery.cookie.js"></script>
function isCookieExists(cookiename) {
return (typeof $.cookie(cookiename) !== "undefined");
}

Categories