Jump to content

Move rows on 2D array


 Share

Recommended Posts

Hi all guys,

which is the best way to move rows inside an array?

Let's say I have the following 2D array

A|0
B|0
C|0
D|0
E|1
F|1

How can I move E -> 0 and F ->1 moving other rows down?
I tried _arrayswap() bv it's not the solution 'cause I don't want to swap elements but just put selected ones on top

Final result should be:

E|1
F|1
A|0
B|0
C|0
D|0

Thanks in advance,

Marco

Edited by marko001
Link to comment
Share on other sites

Can you please tell us why you need to move rows?
Means: Which problem do you want to solve by moving rows E and F?

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Oh sure, no problem.

I'm retrieving crypto assets from KuCoin, using API call, based on an algorythm.

I need to add these retrieved assets to my pool of "already existing assets".

Once I retrieve the list, $aretrievedassets[$i][12], where 2..12 is a bunch of data coming from Exchange, 0 is asset name and 1 is "owned", I add to this array all my owned assets.

So I will have and array of [$i+$j] elements where the first $i are items coming from remote and $j my currently owned assets.

My GUI can accept only $x assets to be viewed per time so I need, first, to put my owned assets on top and only after these all the other assets.

Is it clear or you need the code? nothing secret, by the way.

M.

Link to comment
Share on other sites

Using the _ArrayMultiColSort UDF from @Melba23, this example accomplishes the desired output from your provided example source array.

#include <Array.au3>
Dim $a[][] = [["A",0],["B",0],["C",0],["D",0],["E",1],["F",1]]
_ArrayDisplay($a)

Dim $aSortOrder[][]=[[1,1],[0,0]]
_ArrayMultiColSort($a,$aSortOrder)
_ArrayDisplay($a)

You could also use some combination of _ArrayPush(), _ArrayPop(), _ArrayInsert(), or _ArrayAdd() as necessary to accomplish what you want.

Edited by spudw2k
Link to comment
Share on other sites

You could also script a function reusable in similar cases (e.g. move a block of rows to top or bottom of a 1D/2D array), let's name the function _ArrayRowMove :

#Include <Array.au3>
#Include <MsgBoxConstants.au3>

; Local $aArray[] = ["A0", "B1", "C2", "D3", "E4", "F5", "G6", "H7"]
; or
Local $aArray[][] = [["A",0],["B",1],["C",2],["D",3],["E",4],["F",5],["G",6],["H",7]]

_ArrayDisplay($aArray, "before move")

_ArrayRowMove($aArray, 2, 5) ; rows 2 to 5 moved to top
; or
; _ArrayRowMove($aArray, 2, 5, False) ; rows 2 to 5 moved to bottom

If @error Then
    Msgbox($MB_TOPMOST, "_ArrayRowMove", "error = " & @error)
Else
    _ArrayDisplay($aArray, "after move")
EndIf

;==================================================================
Func _ArrayRowMove(ByRef $aArray, $iStart, $iEnd, $bTopDest = True)

    If Not IsArray($aArray) Then Return SetError(1, 0, 0)

    Local $aBackup, $iDims, $iRows, $iCols, $iInterval, $iInc = -1
    $iDims = UBound($aArray, $UBOUND_DIMENSIONS)
    $iRows = UBound($aArray, $UBOUND_ROWS)
    $iCols = UBound($aArray, $UBOUND_COLUMNS) ; always 0 for 1D array (+++)
    
    If $iDims < 1 Or $iDims > 2 Then Return SetError(2, 0, 0)
    If $iRows = 0 Then Return SetError(3, 0, 0) ; not sure about this test

    If $iStart = Default Or $iStart < 0 Then $iStart = 0
    If $iEnd = Default Or $iEnd > $iRows - 1 Then $iEnd = $iRows - 1
    $iInterval = $iEnd - $iStart
    If $iInterval < 0 Then Return SetError(4, 0, 0)

    $aBackup = $aArray

    If $iDims = 1 Then ; 1D
        If $bTopDest Then ; move to top
            For $i = $iStart -1 To 0 Step -1
                $iInc += 1 ; 0+
                $aArray[$iEnd - $iInc] = $aBackup[$i]
            Next
            For $i = 0 To $iInterval
                $aArray[$i] = $aBackup[$iStart + $i]
            Next
        Else ; move to bottom
            For $i = $iEnd +1 To $iRows -1
                $iInc += 1 ; 0+
                $aArray[$iStart + $iInc] = $aBackup[$i]
            Next
            $iInc = -1
            For $i = $iRows -1 - $iInterval To $iRows -1
                $iInc += 1 ; 0+
                $aArray[$i] = $aBackup[$iStart + $iInc]
            Next
        EndIf
    Else ; 2D
        If $bTopDest Then ; move to top
            For $i = $iStart -1 To 0 Step -1
                $iInc += 1 ; 0+
                For $j = 0 To $iCols -1
                    $aArray[$iEnd - $iInc][$j] = $aBackup[$i][$j]
                Next
            Next
            For $i = 0 To $iInterval
                For $j = 0 To $iCols -1
                    $aArray[$i][$j] = $aBackup[$iStart + $i][$j]
                Next
            Next
        Else ; move to bottom
            For $i = $iEnd +1 To $iRows -1
                $iInc += 1 ; 0+
                For $j = 0 To $iCols -1
                    $aArray[$iStart + $iInc][$j] = $aBackup[$i][$j]
                Next
            Next
            $iInc = -1
            For $i = $iRows -1 - $iInterval To $iRows -1
                $iInc += 1 ; 0+
                For $j = 0 To $iCols -1
                    $aArray[$i][$j] = $aBackup[$iStart + $iInc][$j]
                Next
            Next
        EndIf
    EndIf

    Return 1 ; success
EndFunc

Update Dec 23, 2022
* Added code for 1D array
* Added error checking

Edited by pixelsearch
Update
Link to comment
Share on other sites

 

#include <Array.au3>

Dim $aArray[][] = [["A", 0], ["B", 0], ["C", 0], ["D", 0], ["E", 1], ["F", 1]]

_ArrayDisplay(_ArrPopToTop($aArray, "B|D|F"))
_ArrayDisplay(_ArrPopToTop($aArray, "D|E"))
_ArrayDisplay(_ArrPopToTop($aArray, "C"))

Func _ArrPopToTop($a, $val = "", $index = 0)
    Local $asplit = StringSplit($val, "|", 3)
    _ArrayReverse($asplit)
    For $j = 0 To UBound($asplit) - 1
        $x = _ArraySearch($a, $asplit[$j], "", "", "", 0)
        _ArrayInsert($a, $index, _ArrayExtract($a, $x, $x))
        _ArrayDelete($a, $x + 1)
    Next
    Return $a
EndFunc

 

Edited by Deye
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...