CSV string to array

A little while ago I had a heap of constants that I needed to iterate through, and wanted to automatically define them.

The other day, whilst searching the forum for an answer to something else, I find that others have had similar problems, but theirs eventually turned out to be slightly different:



What I was looking for was a readCsv() sort of function that you get in Python or R, with the following characteristics:

  • Only operates on a small number of values – I wanted to avoid the pain of hand-coding them by hand into an AFL variable/s, and potential errors.
  • Not enough to values to warrant putting them into a dedicated symbol through AddToComposite()
  • They need to be “portable” between databases. AddToComposite ties them to a single DB, needing them to be load them into each DB.
  • Doesn’t need the might and power of a matrix.

The code for numbers and dates:

// ---
function CsvNumsToArr(inpStr, inpValSep)
/*
This function takes a comma-separated list of numerical values, and returns an array with
those values, starting at the 0th element.

Ideally, use it when you want to bulk-load a list of values that you'll use for looping.

Note: only suitable for numerical values, no strings allowed!!
*/
{
	if (inpStr != "")
	{
		cnsNumVals = StrCount(inpStr, inpValSep) + 1 ;
		result = Null ;
		
		for (loop = 0; (loop < cnsNumVals) AND (loop < BarCount); loop ++)
		{
			// Convert each string to a number, and put it into the array
			result[loop]	= StrToNum(StrExtract(inpStr, loop)) ;		//  separator = inpValSep)
		}
	}
	else
		result = Null ;
	
	// Emit the new array of values
	return result ;
}



// ----------
		function CsvDatesToArr(inpStr, inpValSep)
/*
This function takes a comma-separated list of dates, and returns an array with
dateTime values, starting at the 0th element.

Ideally, use it when you want to bulk-load a list of dates that you'll use for looping.

Inputs:
-	"inpStr": a coma-separated string of dates.
-	"inpValSep": a single character used to separate the values, eg a comma ","

Notes: 
-	only suitable for holding dates as DateTime values, no strings allowed!!
-	beware, that the actual values of DateTime variables/ values looks strange, but that's
	just because of how they've been bit-set coded into a 32-bit number (the default used by AmiBroker).
*/
{
	if (inpStr != "")
	{
		cnsNumVals = StrCount(inpStr, inpValSep) + 1 ;
		result = Null ;
		
		for (loop = 0; (loop < cnsNumVals) AND (loop < BarCount); loop ++)
		{
			// Convert each string to a number, and put it into the array
			//result[loop]	= StrToNum(StrExtract(inpStr, loop)) ;		//  separator = inpValSep)
			strPiece		= StrExtract(inpStr, loop) ;
			strPiece		= StrReplace(strPiece, "'", "") ;		// Need to remove any quotation marks
			result[loop]	= StrToDateTime(clcExtract);   
		}
	}
	else
		result = Null ;
	
	// Emit the new array of values
	return result ;
}

Sample data and code to convert it to an array might look like this:

strOfConsts = "0.0001, 0.0005, 0.001, 0.002, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100" 
arrOfConsts = CsvTextToArr(strOfConsts, ",") ;

It’s not the tightest code, but it works for me. I’ll get around to improving it …

That is incorrect approach.

Use ASCII importer instead of trying to code that.
http://www.amibroker.com/guide/d_ascii.html
http://www.amibroker.com/guide/w_impwizard.html

ASCII imports can be automated http://www.amibroker.com/guide/objects.html

Or if you really must code something for sake of coding, use MxFromString and then MxGetBlock to get array.