Jump to content
Sign in to follow this  
rony2006

Delete array row based on filter

Recommended Posts

rony2006

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

 

Share this post


Link to post
Share on other sites
JLogan3o13

@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

√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites
iamtheky
#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

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

Share this post


Link to post
Share on other sites
iamtheky

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

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

Share this post


Link to post
Share on other sites
rony2006

Thanks guys but how I can obtain only rows were 1x is present?

Share this post


Link to post
Share on other sites
AdamUL

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

Share this post


Link to post
Share on other sites
mikell

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

 

  • Like 1

Share this post


Link to post
Share on other sites
iamtheky

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:


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

Share this post


Link to post
Share on other sites
mikell
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
  • Like 2

Share this post


Link to post
Share on other sites
AdamUL

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

 

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  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.