Delete field from record

Hi,

Given building a record in this manner:

set the_rec to {}
set the_rec to the_rec & {a:1}
set the_rec to the_rec & {b:2}
set the_rec to the_rec & {c:3}
return the_rec

how can you delete field ‘a’ from the_rec?

Editted: without hacking the text of the script. That’s the last option.

Thanks,

I changed it. What if you build the record this way:

set the_rec to {}
set sub_rec to {a:1}
set the_rec to the_rec & sub_rec
set sub_rec to {b:2}
set the_rec to the_rec & sub_rec
set sub_rec to {c:3}
set the_rec to the_rec & sub_rec
return the_rec

This way you can store sub_rec. Is there a way to delete a sub record?

That’s ok. I have a solution:

property the_rec : {}
property rec_list : {}

set sub_rec to {a:1}
set end of rec_list to sub_rec
set the_rec to the_rec & sub_rec
set sub_rec to {b:2, c:3}
set end of rec_list to sub_rec
set the_rec to the_rec & sub_rec
set sub_rec to {d:4}
set end of rec_list to sub_rec
set the_rec to the_rec & sub_rec
rec_list

Now I can delete an item from rec_list and rebuild the_rec. Is there a better way to do this?

This sort of thing probably needs to be dealt with on a per-task basis. Working with record lists is super ugly, and there’s really no good way to universally manipulate them. If you have a predictable set of data, it’s easy to simply reconstruct the list from a temporary one and then replace the original list with the edited new version. The following is a modification of my examples of using script objects to handle making references to items in records. I’ve included the code to add items as well, because you need to keep track of what the key’s you’re using are (since applescript can’t do that for you :()…

property theKeyList : {}
property theRecord : {}

set theAction to (button returned of (display dialog "Select an Action:" buttons {"Cancel", "Delete Key", "Add Key"}))

if theAction is "Add Key" then
	set theKey to (text returned of (display dialog "Enter Key String:" default answer ""))
	set theValue to (text returned of (display dialog ("Enter Value for Key '" & theKey & "':") default answer ""))
	addKeyToRecordList(theKey, theValue) --> Add the new key/value pair to theRecord 
	
else if theAction is "Delete Key" then
	set theKey to choose from list theKeyList
	deleteKeyFromRecordList(theKey) --> Remove the new key/value pair from theRecord 
end if

return theRecord

(****** Subroutines ******)
to deleteKeyFromRecordList(theTargetKey)
	set theNewRecord to {}
	set theNewKeyList to {}
	
	repeat with tmpkey in theKeyList
		set tmpkey to (tmpkey as string)
		if tmpkey is not (theTargetKey as string) then
			copy tmpkey to the end of theNewKeyList
			set theNewRecord to (run script "on run{theNewRecord,theRecord}
	set theNewRecord to theNewRecord & {" & tmpkey & ":(" & tmpkey & " of theRecord)}
	return theNewRecord
end" with parameters {theNewRecord, theRecord})
		end if
	end repeat
	set theKeyList to theNewKeyList
	set theRecord to theNewRecord
end deleteKeyFromRecordList

to addKeyToRecordList(theNewKey, theNewValue)
	copy theNewKey to the end of theKeyList
	
	set theRecord to (run script "on run{theNewKey, theNewValue, theRecord}
	set theRecord to theRecord & {" & theNewKey & ":theNewValue}
	return theRecord
end" with parameters {theNewKey, theNewValue, theRecord})
	
end addKeyToRecordList

This probably isn’t going to be very fast for large or complex record lists, since not only does it have to iterate through them all, it also has to construct a script object for every item so it can rebuild the updated list. Unfortunately, this is required, because it’s really the only way to pass a string as a reference to a key. Ideally, applescript should support references like item named “blah” of theRecord or every key of theRecord. This seems like a huge hole that could be fixed with just a wee bit of work. In every other language, key-value coding is well supported… but not applescript.

Hope that gives you some insights…
j

Hi Jobu,

Thanks for replying.

I don’t understand how you delete a field from a record. Did you do that in your script?

Sorry, but I read it three times and can’t grasp how you can delete a field from a record.

I’ll read your post again tomorrow when I’m less inibriated.

The thing is, say the data is not predictable. For instance, someone may login from nowhere with some unpridictable data, so you ask the person, “Give me a label” for your data. After the person enters a label, you enter a field in the record with the person’s label and the data is entered as the fields value. This can be done.

This way you can access any data by the label without searching.

I guess that’s the ultimate goal.

But, what if the person’s stuff needs to be deleted. Then how can you delete a field from a record. Note that each field needs to be unique. You know that you can access fields of a record easily,and that’s the good part, but how can you delete fields efficiently? That’s the bad part.

I can make workarounds, but I’m thinking that there might be some trick in deleting fields of records. If anybody knows one then please tell.

Thanks,

You can’t delete properties from records any more than you can delete items from lists. You can create a new record containing all the properties of the old record minus the one you don’t want, though the new record’s structure generally needs to be known at compile-time because that’s when properties get defined.

There are hacks that allow records’ structures to be manipulated at run-time (LNS’s ‘List & Record Tools’ osax, AppleMods’ Record library), but these are fundamentally evil and subject to all sorts of caveats, limitations, uncertainties about reliability, etc. However, the only time I know of where you have to do this is when using LNS’s ‘XML Tools’ osax, which very stupidly stores element attributes as records instead of key-value lists, in which case you have to use their ‘List & Records Tools’ osax to deal with those. Most times when this question comes it, it’s because folk are using the wrong type of object for the job.

Case in point. Records are not associative lists, and trying to treat them as if they were is language abuse. If you want an associative list, use an associative list. AppleScript (unlike most other languages) may not provide a native associative list type, but they’re not that hard to write. AppleMods’ Types library contains a couple of good, robust ones you can use for free, so the easiest thing would be to just nab those.

has

Thanks for the confirmation. I couldn’t remember if there was a better way of deleting a field from a record. I fell into the trap again, trying to create dynamic fields.

gl,