Jump to content

Filter an Array


 Share

Recommended Posts

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.

Link to comment
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  ÌÍÙ  È
ÌÜ    ÌÍÙ  ÝÈ
ÌÈ[
Link to comment
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.

Edited by weaponx
Link to comment
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?

Link to comment
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

Link to comment
Share on other sites

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
Link to comment
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
Link to comment
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.

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

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

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

......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!
Link to comment
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.
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...