I can’t get the terminology right for ‘replaceObjectAtIndex’. When I add withObject_(y-1) it won’t compile.
Any suggestions please?
Regards
Santa
set x to 0
repeat
set theClientToFind to theClientList's objectAtIndex_(x)
if tempClientString = theClientToFind as text then
set y to theClientListNumberKeeper's objectAtIndex_(x)
theClientListNumberKeeper's replaceObjectAtIndex_(x) withObject_(y+1)
exit repeat
end if
set x to x + 1
end repeat
You’re not writing the function properly. The declaration goes all together (no spaces between underscores) and then the variables go together inside of parathesis
Now, if someone doesn’t mind, how the heck do I follow Stefans advice to
My code looks like this, but naturally the set y to y+1 part is crashing. I’ve googled, but examples aren’t around.
Regards
Santa
repeat with paragraphCycle in paragraphs of item 1 of tempWholeList -- run through the clients in .dat
try
set tempClientString to my SeparateOutClient(paragraphCycle) as text
if tempClientString ≠"" and tempClientString is not in {","} then
--theClientListArray's addObjectsFromArray_({tempClientString}) --< Make VERY long list
if tempClientString is not in items of theClientListTEMP then
theClientList's addObjectsFromArray_({tempClientString}) --< Make short list of Clients
theClientListNumberKeeper's addObjectsFromArray_({1}) --< Make short list of numbers
set end of theClientListTEMP to tempClientString
else
set x to 0
repeat
set theClientToFind to theClientList's objectAtIndex_(x)
if tempClientString = theClientToFind as text then
set y to theClientListNumberKeeper's objectAtIndex_(x)
set y to y + 1
theClientListNumberKeeper's replaceObjectAtIndex_withObject_(x, (y))
exit repeat
end if
set x to x + 1
end repeat
end if
end if
on error errmsg number errnum
display dialog errmsg & " " & errnum
end try
end repeat
set y to theClientListNumberKeeper’s objectAtIndex_(x) as integer
set y to y+1
theClientListNumberKeeper’s replaceObjectAtIndex_withObject_(x, y)
The “as integer” coerces the NSNumber x to an AS integer (use “as real” if the number has decimals)
Ric
After Edit: I wanted to point out one more thing. When you’re adding one thing to an array, you should use addObject rather then addObjectsFromArray, so:
repeat
set theClientToFind to theClientList's objectAtIndex_(x)
if tempClientString = theClientToFind as text then
set y to theClientListNumberKeeper's objectAtIndex_(x)'s as integer
set y to y + 1
set yObject to current application's NSNumber's numberWithUnsignedInt_(y)
theClientListNumberKeeper's replaceObjectAtIndex_withObject_(x, (yObject))
exit repeat
end if
set x to x + 1
end repeat
It’s not really necessary to do that in ASOC. You can pass AS numbers to cocoa methods without having to convert them explicitly to NSNumbers. I tested my code that I posted above, and if you add this line to the end: “log theClientListNumberKeeper’s objectAtIndex_(x)'s |class|()”, you get NSCFNumber.
Also don’t use unsignedInt because applescript’s integers aren’t unsigned ints. They are more like double types because an unsignedInt has a value between 0 and 4294967295 (32 bit number) and signed ints (int) can have values from -2147483647 till 2147483647 (31 bit number + 1 bit for positive or negative number). Applescript’s range is much higher than this so you can have an error with this type. That’s why -2147483647 this is a famous number in error logs. This happens when the computers try to put a long or double value in an int. The system can’t handle it so the number will be the lowest possible number for int or 0 for unsigned ints. It’s safely to use NSNumber’s numberWithDouble_() but like rdelmar suggested this isn’t neccesary because this wil do the applescriptObjC framework for you so you don’t have to hard code it yourself.
Now I just need to see if it’s possible to speed this bit of code up by writing it in ObjC.
Ric in my previous thread you said one of your routines sped up by a factor of 270; well this routine takes over 2000 seconds, which means it has the possibility of speeding up quite considerably.
What are my chances of getting it down a bit? I know the outer loop can’t be altered cause I’m calling a handler, but the ones that interest me are the adding to the arrays and replacing in the array.
I have trouble learning from documentation, but as soon as I see concrete examples I have no problems understanding them.
This bit in particular is VERY slow.
set x to 0
repeat
set theClientToFind to theClientList's objectAtIndex_(x)
if tempClientString = theClientToFind as text then
set y to theClientListNumberKeeper's objectAtIndex_(x) as integer
set y to y + 1
theClientListNumberKeeper's replaceObjectAtIndex_withObject_(x, y)
exit repeat
end if
set x to x + 1
end repeat
Regards
Santa
repeat with paragraphCycle in paragraphs of item 1 of tempWholeList -- run through the clients in .dat
try
set tempClientString to my SeparateOutClient(paragraphCycle) as text
if tempClientString ≠"" and tempClientString is not in {","} then
--theClientListArray's addObjectsFromArray_({tempClientString}) --< Make VERY long list
if tempClientString is not in items of theClientListTEMP then
theClientList's addObject_({tempClientString}) --< Make short list of Clients
theClientListNumberKeeper's addObject_(1) --< Make short list of numbers
set end of theClientListTEMP to tempClientString
else
set x to 0
repeat
set theClientToFind to theClientList's objectAtIndex_(x)
if tempClientString = theClientToFind as text then
set y to theClientListNumberKeeper's objectAtIndex_(x) as integer
set y to y + 1
theClientListNumberKeeper's replaceObjectAtIndex_withObject_(x, y)
exit repeat
end if
set x to x + 1
end repeat
end if
end if
on error errmsg number errnum
display dialog errmsg & " " & errnum
end try
end repeat
You should consider my post in another question (another topic) I answered by using applescript’s way of speeding things up instead of using cocoa for this. if you prefer using cocoa objects then don’t bring your data back to applescript.
Because you’re using applescript’s integers I would say it’s faster to convert from an NSArray to a list once then all the converting you do now. What you’re doing is having a loop in cocoa objects, transfer it’s content to applescript classes and eventually posting it back into an cocoa object. Every loop there are multiple transformations of objects, so if it repeats hundreds of times I can image that it would take long.
The solution for your repeat is to stay in applescript or asoc but don’t mix things up. With asoc look into NSDecimalNumber (mutable subclass of NSNumber) to be able to change object value in your NSMutableArray. Then don’t use updateObject but access the object’s instance method in theArray directly to change it’s value to avoid the overhead you created now.
I’d like to try and get this working using arrays, then attempt (he says laughingly) to write it in ObjC.
According to Ric, I should be able to achieve far faster speed that way.
ATM I’m having problems with this routine, it constantly returns ‘false’. it’s copied from Leons suggestion in my other post.
Once I get this working, I’ll try and work out how NSDecimalNumber works.
Regards
Santa
set myStringToFind to tempClientString
tell current application's NSString to set stringToFind to stringWithString_(myStringToFind)
set theResult to theClientList's containsObject_(stringToFind)
if not theResult then
theClientList's addObject_({tempClientString}) --< Make short list of Clients
theClientListNumberKeeper's addObject_(1) --< Make short list of numbers
Well, the first bit was easy, just need to add ‘as string’ to Leons suggestion.
Thanks Ric, duly amended.
But I’m having real problems with the decimal number bit
Whats wrong with my second line here, please?
tell current application's NSString to set stringToFind to stringWithString_(tempClientString as string)
tell current application's NSNumber to set StartingNumber to decimalNumberWithDecimal_(1)
Ric, I’m trying to get a faster way to arrange my data then the other thread. I think that if I can get this to work as an ObjC piece of code, it will be much faster than going through a giant list of Clients.
I’m having to build up alist of Clients anyway, so why not just increment a ‘parallel’ array as I strike an existing Client.
Trouble is, going through the Clients in a loop in asoc is very slow, but i thought if i could work out how to do it with arrays, writing the ObjC would be much clearer.
ATM I’m having hassles getting DecimalNumber to work, and have no idea how to increment a stored decimal number by 1
It would be nice if I could get the offset of an instance of a particular Client in an array, but it seems i have to use a repeat loop for comparison.
I think (more like I hope) I’m getting the hang of this.
Thanks to Stefans remark about addressing objects in my other thread, I decided to try…
theClientListNumberKeeper's replaceObjectAtIndex_withObject_(x, ((theClientListNumberKeeper's objectAtIndex_(x) as integer) + 1))
and it works.
Now I need to know, is it feasible to convert any of the following to ObjC?
Regards, and thanks
Santa
repeat with paragraphCycle in paragraphs of item 1 of tempWholeList -- run through the clients in .dat
try
set tempClientString to my SeparateOutClient(paragraphCycle) as text
if tempClientString ≠"" and tempClientString is not in {","} then
--set myStringToFind to tempClientString as string
tell current application's NSString to set stringToFind to stringWithString_(tempClientString as string)
--tell current application's NSNumber to set StartingNumber to decimalNumberWithDecimal_(1)
set theResult to theClientList's containsObject_(stringToFind)
if not theResult then
theClientList's addObject_(tempClientString) --< Make short list of Clients
theClientListNumberKeeper's addObject_(1) --< Make short list of numbers
else
set x to 0
repeat
set theClientToFind to theClientList's objectAtIndex_(x) as string
if tempClientString = theClientToFind as text then
theClientListNumberKeeper's replaceObjectAtIndex_withObject_(x, ((theClientListNumberKeeper's objectAtIndex_(x) as integer) + 1))
exit repeat
end if
set x to x + 1
end repeat
end if
end if
on error errmsg number errnum
display dialog errmsg & " " & errnum
end try
end repeat