Jump to content

Recommended Posts

Posted

Hello,

 

I have a big 2d array and some I want to delete all the rows which have elements that are not equal with some strings.

 

I tried this code:

#include <Array.au3>



Local $aBans[5][5] = [[0, 1, 2, 1, 0], _
        [4, 5, 5, 4, 2], _
        [4, "1x", 3, 1, 3], _
        [0, 3, 2, 1, 0], _
        [1, 5, "1x", 4, 1]]



#cs
Local $aResult = _ArrayFindAll($aArray, 0, Default, Default, Default, Default, 4)
_ArrayDisplay($aResult, "Found in Column 4")
#ce

$sDelete = "1x"

; Just to show what you read
_ArrayDisplay($aBans)

; Find the offending name - note you need to use the partial search parameter
$iIndex = _ArraySearch($aBans, $sDelete, 0, 0, 0, 1)

While 1
; And if found - delete
If Not @error Then
    _ArrayDelete($aBans, $iIndex)
EndIf

; Just to show you it has been deleted
_ArrayDisplay($aBans)
Wend

Here I should delete all rows that contains "1x" but the problem is that the script deletes row with index [2] but then it doesn't deletes last row, it deletes row [0, 3, 2, 1, 0] which doesn't not contain "1x". It is wired.

 

How I can solve this problem and how to delete all rows that doesn't contain "1x"?

 

  • Moderators
Posted (edited)

@rony2006 You instantiate $iIndex once, (equal to 2 in your script above) and then in your while loop you keep deleting the same index over and over again. You're basically saying "Delete row 2", "Delete row 2", "Delete row 2", until there is no row 2. You then never escape from your While loop. Try putting your Arraysearch into the While loop:

While 1
    $iIndex = _ArraySearch($aBans, $sDelete, 0, 0, 0, 1)
        If Not @error Then
            _ArrayDelete($aBans, $iIndex)
            _ArrayDisplay($aBans)
        Else
            ExitLoop
        EndIf
Wend

 

Edited by JLogan3o13

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Posted (edited)
#include <Array.au3>

Local $aBans[5][5] = [[0, 1, 2, 1, 0], _
        [4, 5, 5, 4, 2], _
        [4, "1x", 3, 1, 3], _
        [0, 3, 2, 1, 0], _
        [1, 5, "1x", 4, 1]]

local $aOut[0][ubound($aBans , 2)]

$sDelete = "1x"

$sStrip = stringstripws(stringregexpreplace(_ArrayToString($aBans) , "(.*\|" & $sDelete & "\|.*\r?)" , "") , 6)

_ArrayAdd($aOut , $sStrip , 0 , "|" , @CR)

_ArrayDisplay($aOut)

 

edit: sets the second dimension based off the source array

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Posted (edited)

I Func'ed my last effort, because i have hopes and dreams for this effort that are proving faster than walking large arrays.  Added two more conditions in my regex to account for beginning and end of line matches (Im sure there is a better way).

#include <Array.au3>

Local $aBans[5][5] = [[0, 1, 2, 1, 0], _
        [4, 5, 5, 4, "1x"], _
        ["1x" , 4, 3, 1, 3], _
        [0, 3, 2, 1, 0], _
        [1, 5, "1x", 4, 1]]

_ArrayDisplay(_DeleteRowsContaining($aBans , "1x"))

Func _DeleteRowsContaining($aArray , $sDelete)

    local $aOut[0][ubound($aArray , 2)]
        _ArrayAdd($aOut , stringstripws(stringregexpreplace(_ArrayToString($aArray) , "(.*\|" & $sDelete & "\|.*\r?)|(.*\|" & $sDelete & "\r?)|(" & $sDelete & "\|.*\r?)" , "") , 6) , 0 , "|" , @CR)
    return $aOut

EndFunc ; _DeleteRowsContaining

 

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Posted

Here is a way using array functions.  I also created a modified array to test different conditions.  

#include <Array.au3>

Global $aBans[5][5] = [[0, 1, 2, 1, 0], _
        [4, 5, 5, 4, 2], _
        [4, "1x", 3, 1, 3], _
        [0, 3, 2, 1, 0], _
        [1, 5, "1x", 4, 1]]
        
;~ Global $aBans[8][5] = [[0, 1, 2, 1, 0], _
;~         [4, 5, 5, 4, 2], _
;~         [4, "1x", 3, 1, 3], _
;~         [0, 3, 2, 1, 0], _
;~         ["1x", 3, 2, 1, 0], _
;~         [0, 3, 2, 1, 0], _
;~         [0, "1x", 2, 1, 0], _
;~         ["1x", "1x", "1x", "1x", "1x"]]
        

;Show Array.
_ArrayDisplay($aBans, "$aBans")

;Search rows of each column.
Global $sSearchString = "1x"
Global $aResult
Global $sSearchStringRows = ""
For $iCol = 0 To UBound($aBans) - 1
    $aResult = _ArrayFindAll($aBans, $sSearchString, Default, Default, Default, 1, $iCol)
    If @error Then ContinueLoop
    
    ;Record found rows as a string.  
    $sSearchStringRows &= _ArrayToString($aResult, "|") & "|"
Next
$sSearchStringRows = StringTrimRight($sSearchStringRows, 1)

;Convert found rows into an array.
Global $aSearchStringRows = StringSplit($sSearchStringRows, "|", 2)

;Get unique rows only.
$aSearchStringRows = _ArrayUnique($aSearchStringRows, Default, Default, Default, 0)

;Delete the found rows from array.
_ArrayDelete($aBans, _ArrayToString($aSearchStringRows, ";"))

;Display edited array.
_ArrayDisplay($aBans, "$aBans")

;Display rows with search string.
_ArraySort($aSearchStringRows)
_ArrayDisplay($aSearchStringRows, 'Rows with "' & $sSearchString & '"')

 

Adam

Posted

Here it is
ALL credits to iamtheky for the astounding work. This is nothing but a small contribution  :)

#include <Array.au3>

Local $aBans[5][5] = [[0, 1, 2, 1, 0], _
        [4, 5, 5, 4, "1x"], _
        ["1x" , 4, 3, 1, 3], _
        [0, 3, 2, 1, 0], _
        [1, 5, "1x", 4, 1]]

_ArrayDisplay(_DeleteRowsNotContaining($aBans , "1x"))

Func _DeleteRowsNotContaining($aArray , $sDelete)

    local $aOut[0][ubound($aArray , 2)]
         _ArrayAdd($aOut , stringstripws(stringregexpreplace(_ArrayToString($aArray) , "(?m)((?:^|.*?\|)" & $sDelete & "(?:\|.*?|$)\R?)(*SKIP)(*FAIL)|^.*\R?" , "") , 6) , 0 , "|" , @CR)
    return $aOut

EndFunc ; _DeleteRowsNotContaining

 

Posted

regexes that do the NOT operations still eat my lunch.  I'll probably spend the evening deciphering that one, well done.  And that looks to be a far more proper way of picking off the matches at the begin and end of the string.  :thumbsup:

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Posted (edited)
21 minutes ago, iamtheky said:

regexes that do the NOT operations still eat my lunch.

For a long time they ate mine too. And then... I discovered this concept on rexegg.com :

StringRegExpReplace($string, "(KeepThis)(*SKIP)(*FAIL)|(FireThat)", "")

"Sometimes, we want a bit more sophistication to express what we don't want. (...) For this kind of situation, the (*SKIP)(*FAIL) construct is wonderful. With it, instead of cooking up some convoluted negative logic, you express exactly what you want to avoid; if you find it, you skip it; if you don't find it, you match what you want."

Pretty cool  :)

Edited by mikell
Posted

RegEx is nice.  Just for a different type of example.  Here is another option using the ArraySQL UDF.  This requires the SQLite3.dll or SQLite3_x64.dll to be in the script directory.  

#include <ArraySQL.au3>

Global $aBans[5][5] = [[0, 1, 2, 1, 0], _
        [4, 5, 5, 4, 2], _
        [4, "1x", 3, 1, 3], _
        [0, 3, 2, 1, 0], _
        [1, 5, "1x", 4, 1]]

;~ Global $aBans[8][5] = [[0, 1, 2, 1, 0], _
;~         [4, 5, 5, 4, 2], _
;~         [4, "1x", 3, 1, 3], _
;~         [0, 3, 2, 1, 0], _
;~         ["1x", 3, 2, 1, 0], _
;~         [0, 3, 2, 1, 0], _
;~         [0, "1x", 2, 1, 0], _
;~         ["1x", "1x", "1x", "1x", "1x"]]


;Show array.
_ArrayDisplay($aBans)

Global $sSearchString = "1x"

;Rows without search.
Global $sQuery = "SELECT * FROM array WHERE "
For $i = 0 To UBound($aBans, 2) - 1 
    $sQuery &= "column" & $i & " NOT LIKE '%" & $sSearchString & "%' AND "
Next
$sQuery = StringTrimRight($sQuery, 5) & ";"

;Rows with search.
;~ Global $sQuery = "SELECT * FROM array WHERE "
;~ For $i = 0 To UBound($aBans, 2) - 1 
;~  $sQuery &= "column" & $i & " LIKE '%" & $sSearchString & "%' OR "
;~ Next
;~ $sQuery = StringTrimRight($sQuery, 4) & ";"


$aResult = _ArraySQL($aBans, $sQuery)
If @error Then Exit MsgBox(0, "error", $g__sSQLiteError)

;Delete column headers row of SQLite returned array.
_ArrayDelete($aResult, 0)

;Show result array.
_ArrayDisplay($aResult, "$aResult")

 

Adam

 

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
  • Recently Browsing   0 members

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