NSCountedSet in ASOC?

I was trying to enumerate through an NSCountedSet to get the object and its count using this code:

on applicationWillFinishLaunching_(aNotification)
		set cs to current application's NSCountedSet's alloc()'s initWithArray_({"one", "two", "one", "three", "four", "two"})
		repeat with anElement in cs
			log anElement
			log cs's countForObject_(anElement)
		end repeat
	end applicationWillFinishLaunching_

This doesn’t work, and various attempts at coercing anElement didn’t work either (with no coercion, I get an NSAppleEventDescriptor in the first log, and all zeros in the second log).

If after creating the set, I pass that set to the following Objective-C method, it works fine:

+(void)setUp:(NSCountedSet *) theSet {
    for (id anElement in theSet) {
        NSLog (@"%@  %d",anElement, [theSet countForObject:anElement]);
    }
}

Ric

A set looks tantalisingly close to being a list, but as you found, AppleScript’s list stuff doesn’t work with it. However, you can use an enumerator:

set cs to current application's NSCountedSet's alloc()'s initWithArray_({"one", "two", "one", "three", "four", "two"})
set theEnumerator to cs's objectEnumerator()
repeat
	set anElement to theEnumerator's nextObject()
	if anElement = missing value then exit repeat
	log anElement
	log cs's countForObject_(anElement)
end repeat

Thanks Shane, I had tried to use an enumerator using " repeat while theEnumerator’s nextObject() is not missing value" and that didn’t work properly --it only gave me two of the elements for some reason. I also found that you could use NSSet’s allObjects() method to get an array that you could use the fast enumeration syntax on, and get good results. I just thought there should be some simple coercion method to make this work. I’m not sure what goes on behind the scenes with the log command – you can log the counted set, cs, and you get: <NSCountedSet: 0x200428420> (one [2], three [1], two [2], four [1]), so it seems strange that you can’t log an element of the set. Also, in the Objective-C code, if I log the class of anElement, I get NSCFString, so why coercing anElement to a string in AS doesn’t work, I don’t understand.

Ric

That’s because your repeat test calls nextObject(), and so it “swallows” one of the objects each time – you end up getting every second object within the loop.


You can log it OK, it’s the extraction of it to log that 's the issue.

It’s anElement that’s the problem; it doesn’t contain an element. When you use “repeat with x in y” in AS, x contains a reference to an item of the list y. But in this case y isn’t a list – it isn’t even an AS object – so the reference can’t be resolved.

it is curious, though, that the repeat loop loops the correct number of times. So AS is extracting some information there.