I’m looking for solutions to filter an array before a second treatment, which could be applied without further tests.
Say I want to delete all files greater than 500K from a given folder. I could:
get an enumerator, then for every item, test the size and remove big files;
get an enumerator, filter it, then remove all remaining files.
I’d like to know how to implement the solution 2. I’m thinking about another treatment (no deletion this time), like image reducing, which could be applied several times. At each loop, file sizes decrease, and the enumerator become always smaller, until it is empty. At this moment, the treatment is over.
But how to do this? I have seen numerous examples of predicates like @“SELF contains[c] ‘e’”(with small variations) but never a SELF.size > 500000.
I suppose that the solution could be a block, but I have to confess that I’m completely lost…
Well, file size is returned as an unsigned long long integer (aka unsigned long long int) and you’ll get the full bytes count (like 543098 bytes), so why wouldn’t you be able to test it with something like SELF.size > 500000 ?
I would wrap the file size in an NSNumber just to be sure:
[NSNumber numberWithUnsignedLongLong]
And why would you filter files in 2 passes, if you don’t mind me asking? I don’t see the time-saver with this solution. if it’s bigger than 500 k, recycling the file won’t take much longer if it’s 2 mb or 5 tb. unless you want to erase them with zeros or something similar…
Model: MacBookPro8,2
Browser: Safari 534.51.22
Operating System: Mac OS X (10.7)
Well, I don’t like the idea to have multiple passes, but. I didn’t found a way to “equalize” file sizes to a given value. Say we have three files, A is 1225K, B is 254K and C is 78K. If I fix a “maximal size” to 100K, is there a simple calculation to rescale file A (72 ppi) and file B (23400 ppi) to 100K? My present solution is to rescale files to 75% of their dimensions, look at the result, and make a second, third, fourth pass until all files are under 100K.
A highly ineffective method, but.it works (and takes a lot of time).
Doing this in cocoa would be a lot faster… Enumerators like the one you use a super slow in ASOC.
The problem I see is that even if you calculated the image size given the number of pixels in a file, compressions like JPG makes this impossible to predict with any accuracy.
So going the way of cocoa would be my only suggestion so far… Sorry!
leonsimard, I do it in Objective-C. I just can’t imagine doing it in ASOC especially for blocks.
And now, if a loop exceeds half a second on my Mac, I’m starting to get up to make me a coffee… I have rewritten two ASOC apps into Obj-C and I’m not using progress bars anymore: they just don’t have time to show up.
But to pilot the Finder or other app, manipulate window or selections, ASOC remains the best. Just try to grab the Finder selection in Obj-C
I just assumed you did your app in ASOC because you posted in the ASOC forum
I see. But can’t you just grab the selection from the finder in ASOC and give the result back to your Cocoa code? I think it will just be and NSArray of paths as NSStrings. This is what I would do. Only play with ASOC when it is needed. This is what I did in one of my app.
You could try scripting bridge, it would then be 2x as fast. Not easy to use, but you can create the .h file with this terminal command:
sdef /System/Library/CoreServices/Finder.app | sdp -fh --basename Finder
You will end up with a Finder.h file inside your home folder. Then you can use the “selection” object for your needs.
@StefanK (King of Predicates ) : I’ll give a try to this solution to filter an array, it seems to combine predicate and block, the two solutions I had in mind. I’ll be back to tell you if it worked for me.
Of course I tested the code with several folders and size values and the predicate works as expected.
The API to use attributes of NSURL is more up to date and probably faster.
By the way: You’re still writing valueForKey: to get the value of a dictionary key.
The standard method is objectForKey:
valueForKey: could have a different behavior under some circumstances
valueForKey is a KVC method which works with any class (especially with Core Data entities). I never had a problem with it (and there is no objectForKeyPath method in NSDictionary).
Under what circumstances could it be a problem?
For NSURL, yes, I read these “you should use this instead or that” sentences in the doc. Could it be a sign that NSURL will progressively replace other classes and bring order in these (slightly annoying) different ways to get a specific file? I hope so.
Ok, and. under what circumstances could it be a problem?
I read that valueForKey works with NSString (objectForKey takes any valid object) and it could be problematic when the NSString starts with “@”. Is that all?