Create a function that returns the csv representation of a two dimensional numeric array
Create a function that returns the csv representation of a two dimensional numeric array
Filling a two dimensional array of structs with information from a one dimensional array of structs
I wrote a function that successfully reads a CSV file with the following format for each record:
My function reads the CSV file and creates a one-dimensional array of structs, where each record corresponds to an element in the one-dimensional array of structs.
It’s tricky, because different classes have different numbers of members. I initialized a 2-dimensional array with the dimensions classes * max_num_members and set the values of the 2D array to zero (or, in the case of char arrays, I used spaces that would later be written over by other characters). So, obviously, there will be many values (equal to zero for doubles or white space for char arrays) in the 2D array that have not been changed by copying from the 1D array. I can skip these in my main algorithm using a sentinel.
The goal is to use my nested for loops later in the code to loop over members of the class as the nested loop and loop over classes as the outer loop. That part of the code is finished and working correctly, but I need the data to be read into the array of structs that the algorithm uses. Anyone know how to do this?
The alternative is to read my records from the csv file into a 2D array, but that really just transfers from the problem from one location to another. Class names have no more than ten characters and member names have no more than thirteen characters.
Here is my code:
EDIT: Consider the following data:
Any idea what is wrong here? Is it the data file format?
1 Answer 1
Here’s some mildly fixed code. There were problems with myFile vs csvFile and lie_rec vs csv_rec in the readFile() function.
Otherwise, I simplified record initialization with empty and structure assignment; I used simpler/different loop indexes in places; and added some diagnostic printing.
For this data file (partially randomly generated, partially systematically edited):
I get the following diagnostic output:
followed by the following main output:
If that’s not what you’re expecting, show some sample data and the desired output.
Continued debugging
I’ve also cleaned up the use of strncpy() in the readFile() function. It was not doing what you wanted — it was providing no overflow protection because you specified that the length available was the length of the source string, not the length of the target string. In fact, it was also ensuring that strncpy() was not null terminating the copied string, leaving it blank padded (because of the initialization loops — which were removed in this revision) — something that’s quite hard to spot given the tabular output. The safer_copy() function encapsulates the operation correctly, I believe. It takes the view that overlong names are fatal errors; you can choose to truncate instead if you prefer. I’d then use memmove() (or perhaps memcpy() ) to copy the data and would manually null-terminate the target string). As with most things, there’s more than one way to do it (the Perl motto — aka TMTOWTDI) and you need to choose for yourself which is best for your requirements.
One thing this shows is that you can almost always polish a program. I’d not claim this is perfect by any stretch of my imagination. For example, if a line is missing some fields, you get arbitrary garbage stored in the records; the code doesn’t trim leading or trailing blanks from the name fields.
On the sample data from the question, the output is:
Create a function that returns the csv representation of a two dimensional numeric array
Ok, so first
I kept the example as simple as possible, trying not to muddle it with my obvious array of confusion (the pun was intended).
I think I may have a missunderstanding of a dimension:
The third through n line becomes an additional column of 0-41 rows data.
What I want to do is look at the the data’s first few characters on each line so I can find lines of invoice data that pertain to the same invoice and stop the array’s dimensioning there. temporarilly. Once done with that array’s data I would rebuild the array completely starting with the last data line.
Maybe what I am trying to do will not work with an array?
I reread all lines of your algorith in first post, but really can not understand what you finnaly whant to see, but this can be done with arrays!
This because of my fault, sorry. Use this script instead:
‘ CONSTANTS’ |
CONST C_FileName = «input.csv» |
‘ Global OBJECTS’ |
Set objFSO = CreateObject( «Scripting.FileSystemObject» ) |
‘ Script realisation’ |
big = GetArrayDimension (C_FileName) |
Wscript.echo «Now we determinate dimention of array (starting from 0). It’s » & UBound(big,1) & «x» & UBound(big,2) |
big = ReadDataToArray (big, C_FileName) |
Wscript.echo «Now all data is in Array 2D. And we can out all elements. « |
EchoOut2DArray big |
‘——————————————‘ |
‘———-ALL FUNC RELEASE—————‘ |
‘——————————————‘ |
function GetArrayDimension (InFile) |
‘ this function enumerates all lines from line, |
‘ to determinate sizeing of array |
result = array () |
Set InFile = objFSO.OpenTextFile(InFile, 1, False ) |
ReDim result(0,1) |
i = 0 |
do until InFile.AtEndofStream |
strLine = InFile.Readline |
‘ check if not empty line, with correct information |
if ((strLine <> «» ) and (InStr(strLine, «» «») <> 0)) then |
‘ split line to know how many elemtns to process’ |
strLine = split (strLine, «,» ) |
ReDim result(UBound(result)+1, UBound(strLine)) |
i = i + 1 |
end if |
loop |
InFile.Close |
GetArrayDimension = result |
end function |
‘——————————————‘ |
function ReadDataToArray (Arr, InFile) |
‘ After sizing fill array with data, |
Set InFile = objFSO.OpenTextFile(InFile, 1, False ) |
i = 0 |
do until InFile.AtEndofStream |
strLine = InFile.Readline |
WScript.Echo «Process:[» & i & «] » & strLine |
‘ check if not empty line, with correct information |
if ((strLine <> «» ) and (InStr(strLine, «» «») <> 0)) then |
strLine = split (strLine, «,» ) |
for j = 0 to UBound(strLine) |
Arr(i,j) = strLine(j) |
next |
i = i + 1 |
end if |
loop |
ReadDataToArray = Arr |
end function |
‘——————————————‘ |
sub EchoOut2DArray (arr) |
for i=0 to UBound(arr,1) |
for j=0 to UBound(arr,2) |
wscript.echo «[» & i & «,» & j & «] = » & arr(i,j) |
next |
next |
end sub |
I corrected lines 22 and 30. Error was: After read next line size of array is NOT changed.
This done by thous lines (both in function GetArrayDimension and function ReadDataToArray)
‘ check if not empty line, with correct information |
if ((strLine <> «» ) and (InStr(strLine, «» «») <> 0)) then |
So if you delete this line if code in ine function you must delete lines in ither function. BUT this line is important because it prevents incorrect array sizing (see lines below).
2. In my example i use «,» symbol as separator (both in function GetArrayDimension and function ReadDataToArray)
I suggest you use a dictionary object for this then use the keys or items method of the dictionary object to return an array. I’m not really sure what information you want to process in your invoices but i’ve made a script for you that reads your text (csv) input file and then processes each item into an invoice text file. Try modifying this to meet your requirements.
The input file i used to test this with was:
JavaScript array to CSV
I’ve followed this post How to export JavaScript array info to csv (on client side)? to get a nested js array written as a csv file.
The array looks like:
The code given in the link works nicely except that after the third line of the csv file all the rest of the values are on the same line e.g.
name1,2,3
name2,4,5
name3,6,7
name4,8,9name5,10,11 etc etc
Can anyone shed any light on why this is? Same using Chrome or FF.
10 Answers 10
Trending sort
Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.
It falls back to sorting by highest score if no posts are trending.
Switch to Trending sort
The cited answer was wrong. You had to change
Six years have passed now since I wrote this answer. Many things have changed, including browsers. The following was part of the answer:
START of aged part
BTW, the cited code is suboptimal. You should avoid to repeatedly append to a string. You should append to an array instead, and do an array.join(«\n») at the end. Like this:
END of aged part
(Keep in mind that the CSV case is a bit different from generic string concatenation, since for every string you also have to add the separator.)
Anyway, the above seems not to be true anymore, at least not for Chrome and Firefox (it seems to still be true for Safari, though).
To put an end to uncertainty, I wrote a jsPerf test that tests whether, in order to concatenate strings in a comma-separated way, it’s faster to push them onto an array and join the array, or to concatenate them first with the comma, and then directly with the result string using the += operator.
Please follow the link and run the test, so that we have enough data to be able to talk about facts instead of opinions.
Easy way to turn JavaScript array into comma-separated list?
I have a one-dimensional array of strings in JavaScript that I’d like to turn into a comma-separated list. Is there a simple way in garden-variety JavaScript (or jQuery) to turn that into a comma-separated list? (I know how to iterate through the array and build the string myself by concatenation if that’s the only way.)
21 Answers 21
Trending sort
Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.
It falls back to sorting by highest score if no posts are trending.
Switch to Trending sort
Actually, the toString() implementation does a join with commas by default:
I don’t know if this is mandated by the JS spec but this is what most pretty much all browsers seem to be doing.
Or (more efficiently):
Array of Objects with a particular attributes as comma separated.
If you need to use » and » instead of «, » between the last two items you can do this:
Here’s an implementation that converts a two-dimensional array or an array of columns into a properly escaped CSV string. The functions do not check for valid string/number input or column counts (ensure your array is valid to begin with). The cells can contain commas and quotes!
I think this should do it:
Basically all it does is check if the string contains a comma or quote. If it does, then it doubles all the quotes, and puts quotes on the ends. Then it joins each of the parts with a comma.
There are many methods to convert an array to comma separated list
1. Using array#join
The join() method joins all elements of an array (or an array-like object) into a string.
Snippet
2. Using array#toString
The toString() method returns a string representing the specified array and its elements.
Snippet
3. Add []+ before array or +[] after an array
The []+ or +[] will convert it into a string
Proof
will output true
Snippet
Use the built-in Array.toString method
So here is the solution that works for me:
Most of the solutions here would return ‘, apple’ if my array would look like the one in my second example. That’s why I prefer this solution.
I liked the solution at https://jsfiddle.net/rwone/qJUh2/ because it adds spaces after commas:
Or, as suggested by @StackOverflaw in the comments:
Please note that this way is in its very earlier stage, so as of the date of posting this answer, expect incompatibility with older versions of Chrome and other browsers.
Papa Parse handles commas in values and other edge cases.
here you can separate with any char and can take any property list with just foreach
Taking the initial code:
The initial answer of using the join function is ideal. One thing to consider would be the ultimate use of the string.
For using in some end textual display:
For using in a URL for passing multiple values through in a (somewhat) RESTful manner:
Of course, it all depends on the final use. Just keep the data source and use in mind and all will be right with the world.
Seeking help in custom function returning a two-dimensional array that can overflow
To minimize the number of calls, I am trying to use a single call to a function and populate a range (with multiple cells). My function ‘getTotal’ below is working fine but I am stuck in ‘You do not have permission to call setValue’. The range I am trying to populated is C4: C12 (please see attached screen) and I am passing =getTotal(A4: A12, B4: B12) to the function. The function is called from C16.
We can’t call setValue from a custom function but I am not sure whether I can return a two-dimensional array that can overflow into the C4: C12. Documentations and answers here did not help me so I am seeking help.
2 Answers 2
Trending sort
Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.
It falls back to sorting by highest score if no posts are trending.
Switch to Trending sort
If you want to keep using a custom function:
Also, as pointed out by @Cooper «You can return a 2D array, but it can only overflow down and right. Not up and to the left». Meaning you cannot overflow upwards, but only downwards.
This means that you need to call your function from the cell C4 rather than from C16.
In order to modify your formula and enable overflow, you need to create a 2D-array of the required dimensions.
In your case 1 column and 9 rows will set all vEn values. You could also use 13 rows if you want to set both vEn and vEnergy in one go.
Check here for a sample on how to do this.
Applying the sample to your case:
You can define at the beginning of your function: var myArray = [];
and then replace the inside of your for loop ( setSource.getCell(k,1).setValue(vEn); ) with
And finally replace return vEnergy with:
I did not test your code given that I do not have access to «Data», but I hope that my answer helps you to modify your code in the desired way.
Источники информации:
- http://social.technet.microsoft.com/Forums/en-US/46c4097c-a8e1-43e2-8655-3dd5a3f81a5a/dynamically-create-a-two-dimensional-array-from-csv-file?forum=ITCG
- http://stackoverflow.com/questions/18848860/javascript-array-to-csv
- http://stackoverflow.com/questions/201724/easy-way-to-turn-javascript-array-into-comma-separated-list
- http://stackoverflow.com/questions/59890363/seeking-help-in-custom-function-returning-a-two-dimensional-array-that-can-overf