Issue with spaces in List / String

Hi there,

We have a home-grown arrayToStruct function - so that we can customize the key names - as opposed to using the built-in function - which uses the index as the key name.

public array function arrayToStruct(required array arr, required string columnnames='col1') {

	var newArr = [];
	var newStruct = {};
	var rows= ArrayLen(arguments.arr);
	var columns = listlen(arguments.columnnames);
	var thisArr = [];

	if(ArrayLen(arguments.arr) GT 0 AND (ArrayLen(arguments.arr[1]) GTE columns)) {

		for(var i=1;i <= rows;i++) {

			thisArr = arr[i];
			newStruct = {};

			for(var j=1; j <= columns; j++) {

				try {

					newStruct["#listGetAt(arguments.columnnames,j)#"] = thisArr[j];
				} catch(any e) {

					newStruct["#listGetAt(arguments.columnnames,j)#"] = '';
				}
			}

			arrayAppend(newArr,duplicate(newStruct));
		}
	}

	return newArr;

If I use the following code (utilizing our function);

(Please note:
There are NO SPACES after the “commas” of the list items.
There are ONLY TABS between the start of the line and the next item in the list.
)

qOrigFieldsXX = application.dataformat.arrayToStruct(
								qOrigFields,
									"
                                    dsName,
									colId,
									colName,
									colDataTypeId,
									colDataTypeDescr,
									colDataTypeFormat,
									colPosInFile
                                    "

I get a space inserted at the beginning of the keyName of my Struct.

It isn’t instantly obvious, either - because when you dump the structKeyList() : you get the following;

string	colDataTypeFormat, colId, colDataTypeId, colName, colPosInFile, dsName, colDataTypeDescr

Which looks appropriate… a comma, then a space, then the value, then a comma, then a space…
Seems like a “normal” list to me!

I can fix the issue - now that I know what it is doing by using the following code;

qOrigFieldsXX = Application.dataformat.arrayToStruct(
							qOrigFields,
							"dsName,colId,colName,colDataTypeId,colDataTypeDescr,colDataTypeFormat,colPosInFile"

I can’t work out if it is some funkiness with our function that I am not seeing or something else?
But am hoping that someone here might spot the problem?
After the above edit our code is fine and dandy, but I just hate things getting the better of me!

As always : THANKS!

Don’t forget to tell us about your stack!

OS: AWS Linux 2 (CentOS7)
Java Version: 11 (something)
Tomcat Version: 8 (something)
Lucee Version: 5.3.10.133-SNAPHOT

Just trim the listGetAt output?

Hi @Zackster,

But that’s not really what I meant, overall, in the question.
I was actually asking if it was a bug that the whitespace is included in the list item.

After some playing at tryCF, I can conform that Lucee and ACF have identical behaviour.
And that is, that, whitespace IS included in the value of a list member.

Whilst the facts are the facts : It surprised me, nonetheless.
I had “assumed” that the whitespace would be stripped.

Just while typing this - I have had an “aha” moment…
It makes sense that the whitespace isn’t stripped.
A list is just a single string that can be divided by a set delimiter - and everything in between the delimiters is “data”…

(I can see @AdamCameron nodding approvingly - with a slight amount of “I told you so”)
A list is NOT a collection and should NOT be used where a collection is needed.

Onwards and upwards…

Well… indeed. I do say these things for a reason. The only time list operations ought to be used are when:

  • Data coming into the systems is a delimited string: one should convert it to a collection type of some sort before any further processing.
  • At the very last moment before data exits the system, and it needs to be a delimited string.

List operations are generally never appropriate between those two points.
(Before anyone who likes point out exceptions that prove the rule, note I said “generally”).

If anyone is still bamboozled by Gavin’s situation, this demonstrates it:

<cfsetting enablecfoutputonly="true">
<cfset l = "
                                    dsName,
									colId,
									colName,
									colDataTypeId,
									colDataTypeDescr,
									colDataTypeFormat,
									colPosInFile
                                    "
>

<cfloop list="#l#" item="element">
    <cfoutput><pre>[#element#]</pre><br></cfoutput>
</cfloop>

Output:

[
                                    dsName]

[
									colId]

[
									colName]

[
									colDataTypeId]

[
									colDataTypeDescr]

[
									colDataTypeFormat]

[
									colPosInFile
                                    ]

The incorrect assessment Gavin made is in two parts:

  • There is space before each element because he put it there. The question should not have been “what’s Lucee doing wrong?”, it should have been “what am I doing wrong?”. It is really really unlikely that the system (any system) is gonna have bugs in well-trod ground like string parsing.
  • Seemingly forgetting that browsers collapse consecutive spaces. So whilst it might have looked like “a space” when viewed in a browser could be any amount of whitespace in the underlying data / output. When troubleshooting string issues like this, don’t use a browser, look at the actual data. I can’t help but think had Gavin seen the amount and nature of the “space” he’d’ve quickly gone “ah shit of course, that’s my indentation. Duh”, and moved on far more quickly than he did.

NB: everyone falls foul of this at least once.

Summary:

  • Don’t use lists except at the boundaries of the system.
  • When faced with unexpected behaviour, start from the position that it’s your fault, not anyone else’s. You’ll get to the solution quicker.
  • Don’t troubleshoot string issues via how a browser renders that string.
1 Like