Sign in to follow this  
Followers 0
williamk

Filter an Array

30 posts in this topic

Am creating a file list array and want to go through the array and delete all elements that don't meet my criteria. The first 8 characters of each element in the array represent a date (ie 20070801) and it is the date I want to filter by. So to filter the array to consist of only elements between 08/02/2007 and 08/03/2007 I wrote the following:

#include <file.au3>
#include <array.au3>
#include <Date.au3>
$dirpath = "D:\Datatrack\";set the path for the folder where the data extraction files are
$sfilter = "*.PRO"; set the filter for the files you want to extract data from
$FileList = _FileListToArray($dirpath, $sfilter, 1);get the list of files you want to extract data from
If @Error=1 Then
    MsgBox (0,"","No Files\Folders Found.")
    Exit
EndIf
For $MA = 1 to $FileList[0]
    $fd = StringLeft($FileList[$MA],8)
    if $fd NOT <= 20070802 or $fd NOT >= 20070803 Then
    _ArrayDelete ($FileList, $MA)
    Endif
Next
_ArrayDisplay ($FileList)

This does not work though. Seems to be hanging up on the StringLeft command. Can anyone tell me what I am doing wrong? Thanks.

Share this post


Link to post
Share on other sites



Am creating a file list array and want to go through the array and delete all elements that don't meet my criteria. The first 8 characters of each element in the array represent a date (ie 20070801) and it is the date I want to filter by. So to filter the array to consist of only elements between 08/02/2007 and 08/03/2007 I wrote the following:

#include <file.au3>
#include <array.au3>
#include <Date.au3>
$dirpath = "D:\Datatrack\";set the path for the folder where the data extraction files are
$sfilter = "*.PRO"; set the filter for the files you want to extract data from
$FileList = _FileListToArray($dirpath, $sfilter, 1);get the list of files you want to extract data from
If @Error=1 Then
    MsgBox (0,"","No Files\Folders Found.")
    Exit
EndIf
For $MA = 1 to $FileList[0]
    $fd = StringLeft($FileList[$MA],8)
    if $fd NOT <= 20070802 or $fd NOT >= 20070803 Then
    _ArrayDelete ($FileList, $MA)
    Endif
Next
_ArrayDisplay ($FileList)

This does not work though. Seems to be hanging up on the StringLeft command. Can anyone tell me what I am doing wrong? Thanks.

this line is not good

if $fd NOT <= 20070802 or $fd NOT >= 20070803 ThenoÝ÷ ÚØ^~*ìµÊ'v+b¢w¥h§j׬z÷«ÊX§{­§Zµè+y«^®ØZÏöz÷§¶­ï?ßlÊ°j{ZÛazÇ¢w¢wb¶*'zX¦v­zǯz¼­)àë,¶§óýâÉnv)඼ÿmý²ØZ·*.Á©í©±éìy·­µêí¢
0ØZºÚ"µÍY  ÌÍÙ  È
ÌÜ    ÌÍÙ  ÝÈ
ÌÈ[

1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

The StringLeft isn't working because the filenames are strings in the array and you're comparing them to integers in your "if" statement. Wrap quotes around them.

Edited by weaponx

Share this post


Link to post
Share on other sites

The StringLeft isn't working because the filenames are strings in the array and you're comparing them to integers in your "if" statement. Wrap quotes around them.

Ok so I changed it to:

[CODE}
For $MA = 1 to $FileList[0]
$fd = StringLeft($FileList[$MA],8)
if $fd < "20070802" or $fd > "20070803" Then
_ArrayDelete ($FileList, $MA)
Endif
Next
_ArrayDisplay ($FileList)

But I get the error "Array variable has incorrect number of subscripts or subscript dimension range exceeded.:" on the StringLeft command. What does that mean?

Share this post


Link to post
Share on other sites

Thats because _ArrayDelete is resizing your array after each delete but your loop is relying in the size of the array stored in element zero.

Share this post


Link to post
Share on other sites

Ok so I changed it to:

[CODE}
For $MA = 1 to $FileList[0]
$fd = StringLeft($FileList[$MA],8)
if $fd < "20070802" or $fd > "20070803" Then
_ArrayDelete ($FileList, $MA)
Endif
Next
_ArrayDisplay ($FileList)

But I get the error "Array variable has incorrect number of subscripts or subscript dimension range exceeded.:" on the StringLeft command. What does that mean?

your for loop is running too many times because you're deleting items but not decrementing the upper bound of your for loop. add the line

$FileList[0] --

after your _arrayDelete


1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

That syntax won't work in AutoIT you have to use $FileList[0] -= 1

Share this post


Link to post
Share on other sites

That syntax won't work in AutoIT you have to use $FileList[0] -= 1

oops, java flashback

1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

your for loop is running too many times because you're deleting items but not decrementing the upper bound of your for loop. add the line

$FileList[0] --

after your _arrayDelete

I tried the $FileList[0] but that gave me a "= expected" error so it want to know the value of the variable. I than tried the following, but get the same error:

$a=0
For $MA = 1 to $FileList[$a]
    $fd = StringLeft($FileList[$MA],8)
    if $fd < "20070802" or $fd > "20070803" Then
    _ArrayDelete ($FileList, $MA)
    $a = $a-1
    Endif
Next
_ArrayDisplay ($FileList)
Edited by williamk

Share this post


Link to post
Share on other sites

I tried the $FileList[0] but that gave me a "= expected" error so it want to know the value of the variable. I than tried the following, but get the same error:

$a=0
For $MA = 1 to $FileList[$a]
    $fd = StringLeft($FileList[$MA],8)
    if $fd < "20070802" or $fd > "20070803" Then
    _ArrayDelete ($FileList, $MA)
    $a = $a-1
    Endif
Next
_ArrayDisplay ($FileList)
your first line on that last section should be $a = $FileList[0] instead of $a = 0

1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

your first line on that last section should be $a = $FileList[0] instead of $a = 0

Tried that, didn't work. So I tried this:

For $MA = 1 to $FileList[$a]
    $fd = StringLeft($FileList[$MA],8)
    MsgBox(4096, "emp detail records", "Number of emp detail records for profile is:" & $fd)
    $fdi = int($fd)
;MsgBox(4096, "emp detail records", "Number of emp detail records for profile is:" & $fdi)
    if $fdi < 20070802 or $fdi > 20070803 Then
    _ArrayDelete ($FileList, $MA)
    $a = $FileList[0]-1
    Endif
Next
;$FileList[0] = UBound($FileList) - 1
_ArrayDisplay ($FileList)

This runs but just displays the entire array and does no filtering. I also figured I had to convert my string to an integer so I so accurately use the <>. Arg this is frustrating.

Share this post


Link to post
Share on other sites

Tried that, didn't work. So I tried this:

For $MA = 1 to $FileList[$a]
    $fd = StringLeft($FileList[$MA],8)
    MsgBox(4096, "emp detail records", "Number of emp detail records for profile is:" & $fd)
    $fdi = int($fd)
;MsgBox(4096, "emp detail records", "Number of emp detail records for profile is:" & $fdi)
    if $fdi < 20070802 or $fdi > 20070803 Then
    _ArrayDelete ($FileList, $MA)
    $a = $FileList[0]-1
    Endif
Next
;$FileList[0] = UBound($FileList) - 1
_ArrayDisplay ($FileList)

This runs but just displays the entire array and does no filtering. I also figured I had to convert my string to an integer so I so accurately use the <>. Arg this is frustrating.

To loop through arrays while changing their size you must use While,because For only queries the stop value at the first iteration.

Share this post


Link to post
Share on other sites

To loop through arrays while changing their size you must use While,because For only queries the stop value at the first iteration.

OK so I would need to write it something like below, but what do I condition the WHILE statement on ?

$MA = $FileList[0]
while $MA ?????
    $fd = StringLeft($FileList[$MA],8)
    MsgBox(4096, "emp detail records", "Number of emp detail records for profile is:" & $fd)
    $fdi = int($fd)
;MsgBox(4096, "emp detail records", "Number of emp detail records for profile is:" & $fdi)
    if $fdi < 20070802 or $fdi > 20070803 Then
    _ArrayDelete ($FileList, $MA)
    $MA = $MA-1
    Endif

Share this post


Link to post
Share on other sites

This appears to work:

#include <file.au3>
#include <array.au3>
#include <Date.au3>
$dirpath = "D:\Datatrack\";set the path for the folder where the data extraction files are
$sfilter = "*.PRO"; set the filter for the files you want to extract data from
$FileList = _FileListToArray($dirpath, $sfilter, 1);get the list of files you want to extract data from
If @Error=1 Then
    MsgBox (0,"","No Files\Folders Found.")
    Exit
EndIf
$MA = $FileList[0]
While $MA >= 1
    $fd = StringLeft($FileList[$MA],8)
    MsgBox(4096, "emp detail records", "Number of emp detail records for profile is:" & $fd)
    $fdi = int($fd)
    ;MsgBox(4096, "emp detail records", "Number of emp detail records for profile is:" & $fdi)
    if $fdi < 20070802 or $fdi > 20070803 Then
        _ArrayDelete ($FileList, $MA)
    EndIf
    $MA = $MA - 1
WEnd
_ArrayDisplay ($FileList)

BlueBearrOddly enough, this is what I do for fun.

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

OK so I would need to write it something like below, but what do I condition the WHILE statement on ?

$MA = $FileList[0]
while $MA ?????
    $fd = StringLeft($FileList[$MA],8)
    MsgBox(4096, "emp detail records", "Number of emp detail records for profile is:" & $fd)
    $fdi = int($fd)
;MsgBox(4096, "emp detail records", "Number of emp detail records for profile is:" & $fdi)
    if $fdi < 20070802 or $fdi > 20070803 Then
    _ArrayDelete ($FileList, $MA)
    $MA = $MA-1
    Endif
basically you are just setting your exit condition to be whenever your iterator is equal to your upper bound

$y = $FileList[0]
$x = 1
while $x <= $y
if $fdi < 20070802 or $fdi > 20070803 Then
    _ArrayDelete ($FileList, $MA)
$y = $y - 1
else
$x = $x + 1
    Endif
wend

***edit*** typo'd

Edited by cameronsdad

1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

basically you are just setting your exit condition to be whenever your iterator is equal to your upper bound

$y = $FileList[0]
$x = 1
while $x <= $y
if $fdi < 20070802 or $fdi > 20070803 Then
    _ArrayDelete ($FileList, $MA)
$y = $y - 1
else
$x = $x + 1
    Endif
wend

***edit*** typo'd

Think we are almost there. If I run the below my array is reduced from 121 elements to 51 elements, however I should only end up with 3 elements. Any ideas?

$y = $FileList[0]
$x = 1
while $x <= $y
    $fd = StringLeft($FileList[$y],8)
    $fdi = int($fd)
if $fdi < 20070802 or $fdi > 20070803 Then
    _ArrayDelete ($FileList, $y)
$y = $y - 1
else
$x = $x + 1
    Endif
wend

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

I think I'd attack it like this:

#include <Array.au3>
#include <date.au3>

Dim $array[4]
$array[1] = "20070802 some other text"
$array[2] = "20070801 some other text"
$array[3] = "20070804 some other text"

$start = _DateToDayValue("2007","08","02") ;this is the start date (YYYY,MM,DD)
$end = _DateToDayValue("2007","08","03")  ;this is the end date (YYYY,MM,DD)

for $i = (UBound($array) - 1) to 1 step -1
    
    $date = _DateToDayValue(StringMid($array[$i],1,4),StringMid($array[$i],5,2),StringMid($array[$i],7,2))
    
    if  $date < $start or $date > $end Then
        _ArrayDelete($array,$i)
    EndIf
Next

_ArrayDisplay($array)

....only the string "20070802 some other text" is left in the array.

Hope this helps.

Edited by andybiochem

- Table UDF - create simple data tables - Line Graph UDF GDI+ - quickly create simple line graphs with x and y axes (uses GDI+ with double buffer) - Line Graph UDF - quickly create simple line graphs with x and y axes (uses AI native graphic control) - Barcode Generator Code 128 B C - Create the 1/0 code for barcodes. - WebCam as BarCode Reader - use your webcam to read barcodes - Stereograms!!! - make your own stereograms in AutoIT - Ziggurat Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Box-Muller Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Elastic Radio Buttons - faux-gravity effects in AutoIT (from javascript)- Morse Code Generator - Generate morse code by tapping your spacebar!

Share this post


Link to post
Share on other sites

Think we are almost there. If I run the below my array is reduced from 121 elements to 51 elements, however I should only end up with 3 elements. Any ideas?

$y = $FileList[0]
$x = 1
while $x <= $y
    $fd = StringLeft($FileList[$y],8)
    $fdi = int($fd)
if $fdi < 20070802 or $fdi > 20070803 Then
    _ArrayDelete ($FileList, $y)
$y = $y - 1
else
$x = $x + 1
    Endif
wend
well, first lets identify why there are more elements than there should be. are there invalid (outside of range) elements left after stepping through the array?

1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

......as per my code above but using your array populator:

#include <file.au3>
#include <array.au3>
#include <Date.au3>

$dirpath = "D:\Datatrack\";set the path for the folder where the data extraction files are
$sfilter = "*.PRO"; set the filter for the files you want to extract data from
$array = _FileListToArray($dirpath, $sfilter, 1);get the list of files you want to extract data from
If @Error=1 Then
    MsgBox (0,"","No Files\Folders Found.")
    Exit
EndIf

$start = _DateToDayValue("2007","08","02");this is the start date (YYYY,MM,DD)
$end = _DateToDayValue("2007","08","03");this is the end date (YYYY,MM,DD)

for $i = (UBound($array) - 1) to 1 step -1
    
    $date = _DateToDayValue(StringMid($array[$i],1,4),StringMid($array[$i],5,2),StringMid($array[$i],7,2))
    
    if  $date < $start or $date > $end Then
        _ArrayDelete($array,$i)
    EndIf
Next

_ArrayDisplay($array)
Edited by andybiochem

- Table UDF - create simple data tables - Line Graph UDF GDI+ - quickly create simple line graphs with x and y axes (uses GDI+ with double buffer) - Line Graph UDF - quickly create simple line graphs with x and y axes (uses AI native graphic control) - Barcode Generator Code 128 B C - Create the 1/0 code for barcodes. - WebCam as BarCode Reader - use your webcam to read barcodes - Stereograms!!! - make your own stereograms in AutoIT - Ziggurat Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Box-Muller Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Elastic Radio Buttons - faux-gravity effects in AutoIT (from javascript)- Morse Code Generator - Generate morse code by tapping your spacebar!

Share this post


Link to post
Share on other sites

williamk, did you try my code? does it not work?

#include <file.au3>
#include <array.au3>
#include <Date.au3>
$dirpath = "D:\Datatrack\";set the path for the folder where the data extraction files are
$sfilter = "*.PRO"; set the filter for the files you want to extract data from
$FileList = _FileListToArray($dirpath, $sfilter, 1);get the list of files you want to extract data from
If @Error=1 Then
    MsgBox (0,"","No Files\Folders Found.")
    Exit
EndIf
$MA = $FileList[0]
While $MA >= 1
    $fd = StringLeft($FileList[$MA],8)
    MsgBox(4096, "emp detail records", "Number of emp detail records for profile is:" & $fd)
    $fdi = int($fd)
    ;MsgBox(4096, "emp detail records", "Number of emp detail records for profile is:" & $fdi)
    if $fdi < 20070802 or $fdi > 20070803 Then
        _ArrayDelete ($FileList, $MA)
    EndIf
    $MA = $MA - 1
WEnd
_ArrayDisplay ($FileList)

I think the problem with your code earlier is that you are indexing on $y instead of $x, and so you are actually skipping some values.


BlueBearrOddly enough, this is what I do for fun.

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