ArrayIsDefined and numeric

Contributor ,
Jul 02, 2019 Jul 02, 2019

Copy link to clipboard

Copied

Hi,

Is it possible to check if an Array is defined and in the same CFIF statement check to make sure it's numeric?

Something like:

<cfif ArrayIsDefined(F,2) AND IsNumeric>

Taking it one step further I need to make sure the value is between 1 and 99.

ArrayIsDefined and IsNumeric and GT 0 and LT 100....

Suggestions?

Thanks in advance.

Gary

Views

454

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 02, 2019 Jul 02, 2019

Copy link to clipboard

Copied

<!---  'gte' assumes that the value of myArray[2] may include 1 or 99. If not, use 'gt' instead --->

<cfif isdefined("variables.myArray") and arrayIsDefined(myArray, 2) and isNumeric(myArray[2]) and (myArray[2]-1)*(99-myArray[2]) gte 0>

</cfif>

or

<cfif structKeyExists(variables, "myArray") and arrayIsDefined(myArray, 2) and isNumeric(myArray[2]) and (myArray[2]-1)*(99-myArray[2]) gte 0>

</cfif>

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jul 02, 2019 Jul 02, 2019

Copy link to clipboard

Copied

Hi Gary,

Sure, you can just use the AND operator to add multiple conditions to the cfif statement:

<cfif ArrayIsDefined(F,2) AND isNumeric(f[2]) AND f[2] GTE 1 AND f[2] LTE 99>

The conditions are evaluated using short circuit logic, so if ArrayIsDefined(F,2) is false, then isNumeric(f[2]) is never executed.

Pete Freitag

Foundeo Inc.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Jul 02, 2019 Jul 02, 2019

Copy link to clipboard

Copied

Pete,  Thanks... I was struggling with the [ ]. Stupid mistake - I was doing #F[2]#

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 02, 2019 Jul 02, 2019

Copy link to clipboard

Copied

<cfset allAreNumeric_1to99 = true />

<cfswitch expression="#arrayIsDefined(myArray,1)#"><!--- checks if there is at least one item in array --->

     <cfcase value="yes">

          <cfloop from="1" to="#ArrayLen(myArray)#" index="idx">

               <cfif val(myArray[idx]) gte 1 AND val(myArray[idx]) lte 99>

                    <!--- within parameters, do nothing --->

               <cfelse>

                    <cfset allAreNumeric_1to99 = false />

                    <cfbreak />

               </cfif>

          </cfloop>

     </cfcase>

     <cfdefaultcase>It's not an array!  EPIC FAIL!</cfdefaultcase>

</cfswitch>

<cfoutput>#allAreNumeric_1to99#</cfoutput>

HTH,

^ _ ^

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Jul 02, 2019 Jul 02, 2019

Copy link to clipboard

Copied

Wolfshade... That made my novice brain hurt. Now I have to create a test page to play with that code and teach myself what the heck it does. Thanks!!!!

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 02, 2019 Jul 02, 2019

Copy link to clipboard

Copied

It's very simple, actually... it's just that the switch/case might make it appear difficult.  But I prefer switch/case over if/else.

First, I'm setting a variable called allIsNumeric_1to99 to true.

Next, I'm using a switch/case to check if the array is defined; this will also check to make sure that there is at least one item in the array.

If it's an array, then loop through it (iterate it) checking that the value of the current position is between 1 and 99.  If it is less than one or higher than 99, it sets that first variable to false and breaks out of the loop.  (HINT:  Using val() on a string like "a" will produce a value of zero.)

If it's NOT an array (cfdefaultcase), then it displays "It's not an array! EPIC FAIL!".

After the switch/case, it outputs the value of #allAreNumeric_1to99#.  Either true or false.

HTH,

^ _ ^

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Jul 02, 2019 Jul 02, 2019

Copy link to clipboard

Copied

Interesting... So switch / case is a true / false way to do if/else. Seems like that could be very useful for many different reasons.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 03, 2019 Jul 03, 2019

Copy link to clipboard

Copied

ghanna1  wrote

So switch / case is a true / false way to do if/else.

Actually,

switch

case 1

case 2

case 3

..., etc.,

is usually a better alternative to the, often, mind-boggling

if

else if

else if

else if

...,etc.

There is another point.

ghanna1  wrote

I need to make sure the value is between 1 and 99

"The value" suggests one element of the array (that is, at one index). One <cfif> line should therefore suffice.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 03, 2019 Jul 03, 2019

Copy link to clipboard

Copied

ghanna1  wrote

Interesting... So switch / case is a true / false way to do if/else. Seems like that could be very useful for many different reasons.

As I understand it (and if someone can prove that my assertion is incorrect, I'm always open to learning new things), an if/else if/else statement will parse each and every instance, but will actually use only the code that matches the condition.  This is problematic for two reasons: 1) it uses CPU that is unnecessary, and 2) if any of the code in any instance (used or not used) uses something that isn't defined, it will throw an error.  (I know it works that way in ColdFusion; I've experienced it.)

A switch/case statement, however, will go through each case value until it finds the condition, then executes only the code within.  After that, it breaks out of the switch to continue processing what is after it.  So it's more efficient than an if/else if/else statement.  If there is a variable that isn't defined being used in a case that isn't processed, it won't matter.  CPU doesn't see/use/parse it.

Now, I recently learned about something called a "dispatch table".  It's a lot more code, but supposedly _slightly_ more efficient than a switch/case, because it's a data structure that contains properties, and there is no conditional comparison involved - the property is drilled to directly, without comparing to any value or boolean.  (UPDATE: Okay, that does sound odd, because you have to use the value of the property name in order to access said property, but I think you get the gist of what I'm typing.  Accessing a property is faster than comparing values.) 

V/r,

^ _ ^

UPDATE:  Come to think of it, the information I gleaned was from over a decade ago, so things may have changed.  But I have not yet read or heard anything contrary to my above.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Jul 05, 2019 Jul 05, 2019

Copy link to clipboard

Copied

WolfShade​, are you saying the following code will error out on line 5 because an undefined variable is being evaluated even if the first condition is true? This does not happen for me. I tried the code in https://trycf.com/ and https://cffiddle.org/ and I do not get an error.

<cfscript>

    variables.definedVar = 1;

    if (variables.definedVar == 1)

      writeOutput('variables.definedVar is 1');

    else if (variables.undefinedVar == 2 )

      writeOutput('should never get here');

</cfscript>

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 08, 2019 Jul 08, 2019

Copy link to clipboard

Copied

LATEST

The code you provided _should_ error due to variables.undefinedVar not existing, and maybe either Java or CF has improved to correct that.  But years ago your sample code would have errored.  I'm thinking around CF 7 or 8, I experienced this issue in a IF/ELSE conditional that was corrected with a switch/case.  I could not param the variable, don't remember why (that was years ago.)

V/r,

^ _ ^

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 03, 2019 Jul 03, 2019

Copy link to clipboard

Copied

WolfShade  wrote

... I'm using a switch/case to check if the array is defined; this will also check to make sure that there is at least one item in the array.

If it's an array, then loop through it (iterate it) checking that the value of the current position is between 1 and 99.  If it is less than one or higher than 99, it sets that first variable to false and breaks out of the loop.  (HINT:  Using val() on a string like "a" will produce a value of zero.)

If it's NOT an array (cfdefaultcase), then it displays "It's not an array! EPIC FAIL!".

WolfShade, there is a counterexample:

<cfset testVar=[]>

<!--- alternatively --->

<cfset testVar=arrayNew(1)>

TestVar contains no item but is defined and is an array.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 02, 2019 Jul 02, 2019

Copy link to clipboard

Copied

Actually, I could have done that with myArray.map(), but if you're a novice that would most likely make your brain hurt. 

V/r,

^ _ ^

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 02, 2019 Jul 02, 2019

Copy link to clipboard

Copied

Noticing the part about 1 and 99, I updated my post.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 03, 2019 Jul 03, 2019

Copy link to clipboard

Copied

ghanna1  wrote

Is it possible to check if an Array is defined and in the same CFIF statement check...

That calls for something like

isdefined("myArray"), isdefined("variables.myArray") or structKeyExists(variables,"myArray")

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Jul 03, 2019 Jul 03, 2019

Copy link to clipboard

Copied

Every time I post something simple here I walk away learning so many new things! I'm four months into cleaning up craptastic code written in 2008 by a former employee and each pass over the code I'm finding more efficient and more secure ways of doing things. 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 03, 2019 Jul 03, 2019

Copy link to clipboard

Copied

There are a lot of differences between code today and decade-old code.    CF has come a long way, for sure.  The ESAPI, alone, is a big difference.

V/r,

^ _ ^

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines