I get a list of parts of filenames from a folder. I want to count the occurrences of a set of combinations, here represented by fruit. My first problem is that I don’t know how to add the new element to the record from a variable like this:
set theRecord to {}
set theList to {"Apple", "Banana", "Banana", "Banana", "Orange", "Orange"}
repeat with theItem in theList
try
set theItem of theRecord to (theItem of theRecord) + 1
on error
set theRecord to theRecord & {theItem:1}
end try
end repeat
I want theRecord to be {Apple:1, Banana:3, Orange:2}, but get {theItem:6}
My second problem is that I don’t know how to get the elements from the record (if I fill it “manually”}, only the values.
I have a feeling I am doing it in a backwards way here. Working with records is a somewhat new experience to me.
set theRecord to {}
set theList to {"Apple", "Banana", "Banana", "Banana", "Orange", "Orange"}
set theKeyWords to makeUnique(theList)
repeat with theKeyWord in theKeyWords
set end of theRecord to contents of theKeyWord
set end of theRecord to 0
end repeat
repeat with fruit in theList
repeat with i from 1 to (count theRecord) by 2
if item i of theRecord = contents of fruit then
set item (i + 1) of theRecord to (item (i + 1) of theRecord) + 1
end if
end repeat
end repeat
--coerce the list to an record
set theRecord to «class seld» of (record {«class usrf»:theRecord} as record)
on makeUnique(lst)
set newList to {}
repeat with i from 1 to count lst
if item i of lst is not in newList then
set end of newList to item i of lst
end if
end repeat
return newList
end makeUnique
With vanilla and of the box AppleScript you can not (it can with AppleScriptObjC, osaxen or faceless scriptable background apps). But you can also use default values like by concatenating a default values behind it when retreiving:
set theRecord to {Apple:1, Banana:3, Orange:2}
--check to see how many pears are in there:
set nrOfPears to Pear of (theRecord & {Pear:0})
set nrOfApples to Apple of (theRecord & {Apple:0})
return {nrOfPears, nrOfApples}
I’m not sure to understand but if I’m not wrong about your question, there is a ruse to retrieve the full content of the record, so its labels (the elements?) by catching an error:
try
set recordElements to label of theRecord -- or any expression that can compile without error but can't actually run
on error errMsg
set text item delimiters to {"{", "}"}
set allProperties to text item 2 of errMsg
end try
set text item delimiters to ""
allProperties -- returns "Apple:1, Banana:3, Orange:2"
Be aware that this trick ran on an old Applescript version (Lion), not sure it could with recent versions
If you are running 10.9 or later, here’s an alternative. It uses a class known as a counted set, which holds each value only once, but also keeps track the number of times each value is added to the set.
use scripting additions
use framework "Foundation"
set theList to {"Apple", "Banana", "Banana", "Banana", "Orange", "Orange"}
set theDict to current application's NSMutableDictionary's |dictionary|() -- dictionary/record to store values in
set theSet to current application's NSCountedSet's setWithArray:theList
set theEnumerator to theSet's objectEnumerator()
repeat
set aKey to theEnumerator's nextObject()
if aKey = missing value then exit repeat -- no more entries
theDict's setObject:(theSet's countForObject:aKey) forKey:aKey
end repeat
theDict as record
--> {Apple:1, Banana:3, Orange:2}
if you’re running 10.9, it needs to be put in a script library.