 |
 |
Filtering items in an array
|
 |
|
 |
|
Fresh-Faced Recruit
Join Date: Aug 2001
Location: California
Status:
Offline
|
|
I have a little function that I am going to use in a file browsing application that takes an array and returns a filtered array. The array contains the names of files in a certain directory. The filter removes known invisibles from that array. Another thing I need to remove are items that begin with a dot ( "." ).
Here is the function:
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>
NSArray *RemoveHiddenFiles(NSArray *dirArray)
{
NSArray *hiddenFiles = [[NSArray alloc] initWithObjects:<font color = orange>@"bin<font color = red>"</font>, <font color = orange>@"</font>Cleanup At Startup<font color = red>"</font>, <font color = orange>@"</font>cores<font color = red>"</font>, <font color = orange>@"</font>Desktop DB<font color = red>"</font>, <font color = orange>@"</font>Desktop DF<font color = red>"</font>, <font color = orange>@"</font>dev<font color = red>"</font>, <font color = orange>@"</font>etc<font color = red>"</font>, <font color = orange>@"</font>mach<font color = red>"</font>, <font color = orange>@"</font>mach.sym<font color = red>"</font>, <font color = orange>@"</font>mach_kernel<font color = red>"</font>, <font color = orange>@"</font><font color = green>private</font><font color = red>"</font>, <font color = orange>@"</font>sbin<font color = red>"</font>, <font color = orange>@"</font>Temporary Items<font color = red>"</font>, <font color = orange>@"</font>TheFindByContentFolder<font color = red>"</font>, <font color = orange>@"</font>TheVolumeSettingsFolder<font color = red>"</font>, <font color = orange>@"</font>tmp<font color = red>"</font>, <font color = orange>@"</font>Trash<font color = red>"</font>, <font color = orange>@"</font>usr<font color = red>"</font>, <font color = orange>@"</font>var"</font>, <font color = green>nil</font>];
NSMutableArray *filteredFiles = [[NSMutableArray alloc] initWithArray:dirArray];
<font color = green>int</font> num1, num2;
<font color = green>for</font> (num2=<font color = blue>0</font>; num2<[filteredFiles count]; num2++)
{
<font color = green>if</font> ([[[filteredFiles objectAtIndex:num2] substringWithRange:NSMakeRange(<font color = blue>0</font>,<font color = blue>1</font>)] isEqualToString:<font color = orange>@"."</font>])
{
[filteredFiles removeObjectAtIndex:num2];
}
}
<font color = green>for</font> (num1=<font color = blue>0</font>; num1<[hiddenFiles count]; num1++)
{
[filteredFiles removeObject:[hiddenFiles objectAtIndex:num1]];
}
<font color = green>return</font> (NSArray *)filteredFiles;
}
</font>[/code]
Yeah, there are probably some memory leaks, but I will get to those later. The real problem is that when I try to remove files starting with a dot, it only removes .DS_Store and .Trashes.
In my home directory I have a lot more than that (.xinitrc, .gimp, .dillo, etc.). In the root directory there are still .vol and .hidden.
I don't know why the filter won't remove those files, I think there might be something wrong with the for loop, but that is just a guess.
Any help would be greatly appreciated.
|
|
AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH!
|
| |
|
|
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Jan 2001
Location: Virginia, US
Status:
Offline
|
|
When you remove an item from the array, all of its objects above it shift down one slot, and so your index is now incorrect. You should not increment num2 if you remove an object, or start num2 at count-1 and decrement each iteration instead, stopping when num < 0. Or, more cleanly, don't create a copy first but instead only add "validated" objects to the filtered array. Generally, be very careful when removing items from an array you're iterating over -- it's very easy to make mistakes. Removing objects from an array when you're using an NSEnumerator to do the iteration is illegal for this reason.
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>
NSArray *RemoveHiddenFiles(NSArray *dirArray)
{
<font color = green>static</font> NSArray *hiddenFiles = <font color = green>nil</font>;
NSMutableArray *filteredFiles = [NSMutableArray arrayWithCapacity:[dirArray count]];
<font color = green>int</font> num;
<font color = green>if</font> (hiddenFiles == <font color = green>nil</font>)
hiddenFiles = [[NSArray alloc] initWithObjects:<font color = orange>@"bin<font color = red>"</font>, <font color = orange>@"</font>Cleanup At Startup<font color = red>"</font>, <font color = orange>@"</font>cores<font color = red>"</font>, <font color = orange>@"</font>Desktop DB<font color = red>"</font>, <font color = orange>@"</font>Desktop DF<font color = red>"</font>, <font color = orange>@"</font>dev<font color = red>"</font>, <font color = orange>@"</font>etc<font color = red>"</font>, <font color = orange>@"</font>mach<font color = red>"</font>, <font color = orange>@"</font>mach.sym<font color = red>"</font>, <font color = orange>@"</font>mach_kernel<font color = red>"</font>, <font color = orange>@"</font><font color = green>private</font><font color = red>"</font>, <font color = orange>@"</font>sbin<font color = red>"</font>, <font color = orange>@"</font>Temporary Items<font color = red>"</font>, <font color = orange>@"</font>TheFindByContentFolder<font color = red>"</font>, <font color = orange>@"</font>TheVolumeSettingsFolder<font color = red>"</font>, <font color = orange>@"</font>tmp<font color = red>"</font>, <font color = orange>@"</font>Trash<font color = red>"</font>, <font color = orange>@"</font>usr<font color = red>"</font>, <font color = orange>@"</font>var"</font>, <font color = green>nil</font>];
<font color = green>for</font> (num=<font color = blue>0</font>; num<[dirArray count]; num++)
{
NSString *name = [dirArray objectAtIndex:num];
<font color = green>if</font> (![name hasPrefix:<font color = orange>@"."</font>] && ![hiddenFiles containsObject:name])
[filteredFiles addObject:name];
}
<font color = green>return</font> filteredFiles;
}
</font>[/code]
Also as a FYI, the ".hidden" file in a directory contains a list of files that don't show up in Finder. That's actually what Finder uses to filter with for files that don't start with '.'.
Also, your second loop in your original code could have been replaced with [filteredFiles removeObjectsInArray:hiddenFiles] though I did it a different way above. Just for future reference :-)
|
|
|
| |
|
|
|
 |
|
 |
|
Fresh-Faced Recruit
Join Date: Aug 2001
Location: California
Status:
Offline
|
|
Wow, thanks a lot!
I actually tried using the removeobjectsinarray, but it didn't work, probably for the reason you stated.
|
|
AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH!
|
| |
|
|
|
 |
 |
|
 |
|
|
|
|
|

|
|
 |
Forum Rules
|
 |
 |
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is Off
|
|
|
|
|
|
 |
 |
 |
 |
|
 |
|