Jump to content

Delete array row based on filter


 Share

Recommended Posts

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"?

 

Link to comment
Share on other sites

  • Moderators

@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!

Link to comment
Share on other sites

#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

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

Link to comment
Share on other sites

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

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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:

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

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

 

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...