Sign in to follow this  
Followers 0
Odewallrus

Add column to array

25 posts in this topic

Can someone please help me with why this code is not adding a column to the array? I have used it in the past, but cannot seem to figure out what I am missing here.

$sINI = @ScriptDir & "\FileBackup.ini"
$iSource = IniReadSection($sINI, "Source"
Global $FileArray[1]
$FileArray[0]="0"

For $s = 1 To $iSource[0][0]
    $iTypes = StringSplit($iSource[$s][1],",",0)

    For $t = 1 To $iTypes[0]
    $fArray = _FileListToArray_Recursive($iSource[$s][0], "", $iTypes[$t], "", 1, 2, True)
    _ArrayConcatenate($FileArray,$fArray,1)
    Next
Next
$aRows = UBound($FileArray)
$FileArray[0] = $aRows - 1

_ArrayAdd_Column($FileArray)
_ArrayDisplay($FileArray, "Debug: $FileArray")

Func _ArrayAdd_Column($Array)
    Local $aTemp[UBound($Array)][UBound($Array, 0) + 1]
    For $i = 0 To UBound($Array) - 1
        
        For $j = 0 To UBound($Array, 0) - 1
            If UBound($Array, 0) = 1 Then $aTemp[$i][0] = $Array[$i]
            If UBound($Array, 0) > 1 Then $aTemp[$i][$j] = $Array[$i][$j]
        Next
    Next
    Return $aTemp
EndFunc  ;==>_ArrayAdd_Column

Share this post


Link to post
Share on other sites



#3 ·  Posted (edited)

The function returns the modified array, but you never assign the return value to a variable. Like:

$FileArray = _ArrayAdd_Column($FileArray)

The better way would be to use ByRef though.

Also consider

ReDim $FileArray[UBound($FileArray)][UBound($FileArray,2)+1]

Edit: Captian slow to the rescue!

Edited by Tvern

Share this post


Link to post
Share on other sites

The function returns the modified array, but you never assign the return value to a variable. Like:

$FileArray = _ArrayAdd_Column($FileArray)

The better way would be to use ByRef though.

Also consider

ReDim $FileArray[UBound($FileArray)][UBound($FileArray,2)+1]

Edit: Captian slow to the rescue!

THANK YOU!

Share this post


Link to post
Share on other sites

Redim loses the array's previous contents.

...and the _ArrayAdd_Column code above does not take into account the fact that Ubound returns 0 when there's only one column, but is accurate the rest of the time.

Here's a version of _ArrayAdd_Column which takes this into account:

Func _ArrayAdd_Column($Array)
   if UBound($Array, 2) = 0 then                       ;Ubound returns 0 if there is only one column!
      Local $aTemp[UBound($Array, 1)][2]                           ;...so force it manually the first time
      $OrigColCount = 1
   Else
      Local $aTemp[UBound($Array, 1)][UBound($Array, 2) + 1]       ;...otherwise increment normally
      $OrigColCount = UBound($Array, 2)
   EndIf
    
   For $r = 0 To UBound($Array, 1) - 1        
      For $c = 0 To $OrigColCount - 1
         If $OrigColCount = 1 Then                                 ;And single column arrays don't like having a column index reference
            $aTemp[$r][0] = $Array[$r]
         Else
            $aTemp[$r][$c] = $Array[$r][$c]
         EndIf
      Next
   Next

   Return $aTemp
EndFunc

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Redim ONLY loses the array's previous content IF the number of dimensions changes for that array. Edited by iEvKI3gv9Wrkd41u

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Share this post


Link to post
Share on other sites

This function should work to do the trick.

; #FUNCTION# ====================================================================================================================
; Name...........: _ArrayAddColumns
; Description ...: Adds a specified number of columns to an array.
; Syntax.........: _ArrayAddColumns(ByRef $aArrayIn, $NumColCount)
; Parameters ....: $aArrayIn - Array to modify
;                  $NumColCount  - Number of columns to add (default = 1)
; Return values .: Success - New array with columns added
;                  Failure - -1, sets @error
;                  |1 - $aArrayIn is not an array
;                  |2 - $NumColCount is an invalid number
;                  |3 - Array has too many dimensions (2D array max)
; Author ........: Bob Marotte aka BrewManNH
; Remarks .......: This will add any number of columns to a 1D or 2D array of any size and preserves
;                  the contents of the array being modified
; Related .......: _ArrayConcatenate, _ArrayDelete, _ArrayInsert, _ArrayPop, _ArrayPush
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _ArrayAddColumns(ByRef $aArrayIn, $NumColCount = 1)
    If Not IsArray($aArrayIn) Then
        SetError(1)
        Return -1
    EndIf
    If $NumColCount < 1 Then
        SetError( 2)
        Return -1
    EndIf
    Local $iDimensions = UBound($aArrayIn, 0)
    If $iDimensions > 2 Then
        SetError(3)
        Return -1
    EndIf
    Local $NewArrayOut[UBound($aArrayIn)][$iDimensions + $NumColCount + 1]
    For $I = 0 To UBound($aArrayIn) - 1
        If $iDimensions > 1 Then
            For $X = 0 To $iDimensions
                $NewArrayOut[$I][$X] = $aArrayIn[$I][$X]
            Next
        Else
        $NewArrayOut[$I][0] = $aArrayIn[$I]
        EndIf
    Next
    Return $NewArrayOut
EndFunc   ;==>_ArrayAddColumns

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

I don't really see the point of it ...

Func _Array_ColumnAdjust($array, $add) ;; $add can be a positive or negative value.
;~  If 1 Then ;; parameter checkup. [debug]
;~      If Not IsArray($array) Then Exit 9931 ;; IsArray($array) <> 1
;~      If Not (UBound($array, 0) = 1 Or UBound($array, 0) = 2) Then Exit 9932
;~      If Not IsInt($add) Then Exit 9933
;~  EndIf

    If UBound($array, 2) And (UBound($array, 1) * UBound($array, 2) + $add) > Int(2 ^ 24) Then Exit 9939 ;; would cross array max-cel limit.

    If Not UBound($array, 2) Then $array = _array_dim_1to2($array) ;; I would not do this ... not here at least.

    If $add Then
        If UBound($array, 2) + $add < 1 Then Exit 9938
        ReDim $array[UBound($array, 1)][UBound($array, 2) + $add]
    EndIf

    If UBound($array, 2) = 1 Then $array = _array_dim_2to1($array) ;; I would not do this ... not here at least.

    Return $array
EndFunc
Func _array_dim_1to2($array_in)
;~  If 1 Then ;; parameter checkup. [debug]
;~      If Not IsArray($array_in) Then Exit 9911
;~      If Not (UBound($array_in, 0) = 1) Then Exit 9912
;~  EndIf

    If UBound($array_in, 1) * 2 > Int(2 ^ 24) Then Exit 9919 ;; would cross array max-cel limit.

    Local $array_out[UBound($array_in, 1)][1]
    For $i = 0 To UBound($array_in, 1) - 1
        $array_out[$i][0] = $array_in[$i]
    Next

    Return $array_out
EndFunc
Func _array_dim_2to1($array_in)
;~  If 1 Then ;; parameter checkup. [debug]
;~      If Not IsArray($array_in) Then Exit 9921
;~      If Not (UBound($array_in, 0) = 2) Then Exit 9922
;~  EndIf

    Local $array_out[UBound($array_in, 1)]
    For $i = 0 To UBound($array_in, 1) - 1
        $array_out[$i] = $array_in[$i][0]
    Next

    Return $array_out
EndFunc

-3- other minor adjustments.

Edited by iEvKI3gv9Wrkd41u

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Share this post


Link to post
Share on other sites

If you send your function a variable that's not an array it crashes the script. If there are any other error conditions your function exits the script rather than returning an error code and continuing the script. Sending the function an $add parameter of 0 just returns the original script rather than telling the program that it didn't do anything, which might be an issue if you're using a variable that you set to 0 before calling the function, might cause troubleshooting issues in someone's script.

With my version I included error checking and not inadvertantly deleting columns that you didn't want to delete because in my function it is only adding columns and won't accept negative values. After all the function is called _ArrayAddColumns. Plus it returns from the function without killing the script. I wouldn't use an Exit command for errors, I'd use a Return statement and SetError


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

As its intended as example code and its not claiming to be a fully finished UDF ... Its working perfectly in my view.

- Showing ReDim is maintaining the array data, when used correctly.

- Using Array[X][1] trick to simulate a one dimensional array with a two dimensional array.

- And how to check when a requested column change will trigger a max-array size violation. (can of course also be used for a similar AddRow function)

(I don't see any questions. So I leave it at that.)


"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Share this post


Link to post
Share on other sites

This function should work to do the trick.

; #FUNCTION# ====================================================================================================================
; Name...........: _ArrayAddColumns
; Description ...: Adds a specified number of columns to an array.
; Syntax.........: _ArrayAddColumns(ByRef $aArrayIn, $NumColCount)
; Parameters ....: $aArrayIn - Array to modify
;                  $NumColCount  - Number of columns to add (default = 1)
; Return values .: Success - New array with columns added
;                  Failure - -1, sets @error
;                  |1 - $aArrayIn is not an array
;                  |2 - $NumColCount is an invalid number
;                  |3 - Array has too many dimensions (2D array max)
; Author ........: Bob Marotte aka BrewManNH
; Remarks .......: This will add any number of columns to a 1D or 2D array of any size and preserves
;                  the contents of the array being modified
; Related .......: _ArrayConcatenate, _ArrayDelete, _ArrayInsert, _ArrayPop, _ArrayPush
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _ArrayAddColumns(ByRef $aArrayIn, $NumColCount = 1)
    If Not IsArray($aArrayIn) Then
        SetError(1)
        Return -1
    EndIf
    If $NumColCount < 1 Then
        SetError( 2)
        Return -1
    EndIf
    Local $iDimensions = UBound($aArrayIn, 0)
    If $iDimensions > 2 Then
        SetError(3)
        Return -1
    EndIf
    Local $NewArrayOut[UBound($aArrayIn)][$iDimensions + $NumColCount + 1]
    For $I = 0 To UBound($aArrayIn) - 1
        If $iDimensions > 1 Then
            For $X = 0 To $iDimensions
                $NewArrayOut[$I][$X] = $aArrayIn[$I][$X]
            Next
        Else
        $NewArrayOut[$I][0] = $aArrayIn[$I]
        EndIf
    Next
    Return $NewArrayOut
EndFunc   ;==>_ArrayAddColumns

 

This is actually causing the last column in the original array to be overwritten by one of the new columns being added, so I made the following change. Can anyone see a problem arising from this?

           

from

For $X = 0 To $iDimensions

to

For $X = 0 To $iDimensions + 1

Share this post


Link to post
Share on other sites

Actually, you'd need to do this.

; change this line first
Local $NewArrayOut[UBound($aArrayIn)][$iDimensions + $NumColCount] ; <<<<<<<<<<< don't use +1
; then change this line to this
For $X = 0 To  UBound($aArrayIn) - 1

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

OK, I'll do it as soon as I get a chance.

Share this post


Link to post
Share on other sites

New to the site.

Read through this post, as am interested in learning how to add columns from one array to another array.

I know how to create an array etc, but I am a little confuse on this function - latest post in Feb 2014.

I read through the function and tinkered with my two existing arrays but failed miserably.

So assuming I have array ABC - 2D (10 X 10) and a second array XYZ - 2D (10 x 5), I should be able to add XYZ's 5 columns, right?

Any help getting me started would be appreciated.

Share this post


Link to post
Share on other sites

This could do it:

#include <Array.au3>
Local $aArray1[10][10]
Local $aArray2[10][5]

For $i = 0 To UBound($aArray1)-1
    For $j = 0 To UBound($aArray1,2)-1
        $aArray1[$i][$j] = 1
        If $j < UBound($aArray2,2) Then
            $aArray2[$i][$j] = 2
        EndIf
    Next
Next

ReDim $aArray1[UBound($aArray1)][UBound($aArray2,2)+UBound($aArray1,2)]
For $i = 0 To UBound($aArray1)-1
    For $j = UBound($aArray1,2)-1 To UBound($aArray1,2) - UBound($aArray2,2) Step -1
        $aArray1[$i][$j] = $aArray2[$i][$j-UBound($aArray1,2)+UBound($aArray2,2)]
    Next
Next
_ArrayDisplay($aArray1)

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites
jdelaney

 

I read your code and got enlightened a bit - thanks.

Real quick question - it seems I can combine array horizontally but vertically is more a challenge??

Example to add two 2D arrays of 5 row/ 10 column (each) resulting in an update combined array of 5 rows/20 columns works fine.

From what I have read so far trying to make a 10 row/10 column is not fine.

Saw an example of 1D array done but not sure how it would be modified to work for 2 D.

If you could point me in the right direction or advise of pitfalls, I would appreciate it.

Thanks. 

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

horizontal, and vertical (no error checking):

#include <Array.au3>
Local $aArray1[10][10]
Local $aArray2[10][5]

For $i = 0 To UBound($aArray1)-1
    For $j = 0 To UBound($aArray1,2)-1
        $aArray1[$i][$j] = 1
        If $j < UBound($aArray2,2) Then
            $aArray2[$i][$j] = 2
        EndIf
    Next
Next

$aHoriz = $aArray1
$aVert = $aArray1
ReDim $aHoriz[UBound($aHoriz)][UBound($aArray2,2)+UBound($aHoriz,2)]
For $i = 0 To UBound($aHoriz)-1
    For $j = UBound($aHoriz,2)-1 To UBound($aHoriz,2) - UBound($aArray2,2) Step -1
        $aHoriz[$i][$j] = $aArray2[$i][$j-UBound($aHoriz,2)+UBound($aArray2,2)]
    Next
Next
_ArrayDisplay($aHoriz)


ReDim $aVert[UBound($aVert)+UBound($aArray2)][UBound($aVert,2)]
For $i = UBound($aVert)-1 To UBound($aVert) - UBound($aArray2) Step -1
    For $j = 0 To UBound($aArray2,2)-1
        $aVert[$i][$j] = $aArray2[$i-UBound($aVert)+UBound($aArray2)][$j]
    Next
Next
_ArrayDisplay($aVert)
Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites
jdelaney

Thanks, that clears up a lot for such a beginner.

So I expanded and started reading in csv files and have a question.

If I want to read a csv file but only input the first three fields, what is the best way or can it be done?

If I read in the whole csv file I may have a 2D array of 10 rows/10 col , but what if I only want the first three fields (ie first 3 columns)?

I haven't found anything that helps me figure it out yet.

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

You would need to create your own function, or read all of it into and array, and the redim your array to only have 3 columns.

redim

There are already tons of examples to read a csv to an array.  Do a forum search for them.

Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites
jdelaney

 

Hey thanks, giving me the Redim keyword helped great.  Got through the csv file reading effort.

If you could point me in the right direction for the following question, I would appreciate it as i don't know if there is a keyword or something and really don't know what to be looking for.

Back in your example of vertically adding two 2D arrays together, one had all the fields  filled while the  one added was left justified, leaving the trailing columns blank so here is my question.

When working with such arrays as i just described is it possible to make the second array right justified?  Is it an index question or some base value?

I can do this if you point me in the right direction.

Thanks.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0