tracker issue : CF-4205055

select a category, or use search below
(searches all categories and all time range)
Title:

[ANeff] Bug for: inconsistent looping of sparse array

| View in Tracker

Status/Resolution/Reason: To Fix//BugVerified

Reporter/Name(from Bugbase): Aaron N. / ()

Created: 08/23/2019

Components: Language

Versions: 2018

Failure Type: Usability Issue

Found In Build/Fixed In Build: 2018.0.04.314546 /

Priority/Frequency: Normal / Some users will encounter

Locale/System: / Windows 10 64 bit

Vote Count: 0

Issue: CF inconsistently loops a sparse array (bad). Lucee consistently loops a sparse array (good).

History:
- Before CF-3864256's fix, only <cfloop array="#myArray# index="myElement"> skipped undefined/null elements. No other looping construct did this.
- After CF-3864256's fix, for(myElement in myArray) also skipped undefined/null elements. No other looping construct did this.
- Lucee never skips undefined/null array elements during loop.

Steps to Reproduce:

<cfset myQuery = queryNew("myColumn", "varchar", [["foo"],[javaCast("null","")],[],["bar"]])>
<cfset myArray = myQuery.valueArray("myColumn")>

<cfdump var="#myArray#">

<!--- These loop 2 times --->
<cfset i = 0>
<cfloop array="#myArray#" index="myElement">
  <cfoutput>#++i#</cfoutput>
</cfloop>
<hr>
<cfloop array="#myArray#" item="myElement" index="myIndex">
  <cfoutput>#myIndex#</cfoutput>
</cfloop>
<hr>
<cfscript>
  i = 0;
  cfloop(array=myArray, index="myElement") {
	  writeOutput(++i);
  }
  writeOutput("<hr>");
  cfloop(array=myArray, item="myElement", index="myIndex") {
	  writeOutput(myIndex);
  }
  writeOutput("<hr>");
  i = 0;
  for(myElement in myArray) {
	  writeOutput(++i);
  }
  writeOutput("<hr>");
</cfscript>

<!--- These loop 4 times --->
<cfloop from="1" to="#myArray.len()#" index="i">
  <cfoutput>#i#</cfoutput>
</cfloop>
<hr>
<cfscript>
  cfloop(from=1, to=myArray.len(), index="i") {
	  writeOutput(i);
  }
  writeOutput("<hr>");
  myArray.each(function(myElement, myIndex, myArray) {
	  writeOutput(myIndex);
  });
  writeOutput("<hr>");
  myArray.map(function(myElement, myIndex, myArray) {
	  writeOutput(myIndex);
  });
  writeOutput("<hr>");
  myArray.filter(function(myElement, myIndex, myArray) {
	  writeOutput(myIndex);
	  return true;
  });
  writeOutput("<hr>");
  myArray.reduce(function(myResult, myElement, myIndex, myArray) {
	  writeOutput(myIndex);
  });
  writeOutput("<hr>");
</cfscript>

Actual Result: Inconsistent looping of sparse array.

Expected Result: Consistent looping of sparse array.

Suggestion: Match Lucee's behavior (i.e. revert CF-3864256 [which I'd voted for, but, need to retract my vote] and then update <cfloop array="#myArray# index="myElement"> to not skip undefined/null elements).

Related tickets: CF-3864256 and CF-4205052

Related URL: https://www.bennadel.com/blog/3531-coldfusion-2016-skips-over-undefined-elements-with-for-in-array-loop.htm

Attachments:

Comments:

Aaron, I checked your test code with 2018 HF5. They all seem to be looping 4 times. Am I missing something here. Here's the output I get with the slightly modified code I've attached: 1 2 3 4 1| 2| 3| 4| 1|2|3|4| 1|2|3|4| 1|2|3|4| ------------------------- 1| 2| 3| 4| 1|2|3|4| 1|2|3|4| 1|2|3|4| 1|2|3|4| 1|2|3|4| Also, contrary to what you've noted in CF-3864256, Lucee's behavior is not consistent across different looping constructs as well as product versions. Here's the output you get, with the code detailed after the output below: Lucee 5: variable [E] doesn't exist on line 12 Lucee 4.5: a| c| a||c| Test code: <cfoutput>#server.coldfusion.productversion#</cfoutput><br> <cfset a = arrayNew(1)> <cfset a[1] ="a"> <cfset a[3] = "c"> <cfdump var=#a#> <cfloop index="e" array="#a#"> <cfoutput>#e#</cfoutput>| </cfloop> <cfscript> for (e in a){ writeoutput(e); writeoutput("|"); } </cfscript>
Comment by Piyush K.
31654 | October 19, 2019 06:17:54 AM GMT
Aaron, can you pls. check out my last comment.
Comment by Piyush K.
31679 | October 23, 2019 11:10:27 AM GMT