Text file elements to list

Hello, I’m AS newbie and have problem.

I have text file with data:
name1, {10, 20, 30, 40}
name2, {30, 30, 10, 50}
name3, {40, 30, 20, 20}
name4, {50, 10, 50, 10}

I need read this file as list with first item as string and second item as list:
{“name1”, {10, 20, 30, 40}
“name2”, {30, 30, 10, 50}
“name3”, {40, 30, 20, 20}
“name4”, {50, 10, 50, 10}}

or better as nested list
{{“name1”, {10, 20, 30, 40}},
{“name2”, {30, 30, 10, 50}}
{“name3”, {40, 30, 20, 20}}
{“name4”, {50, 10, 50, 10}}}

I can’t convert second element to list. I always get strings.

Thanks

Browser: Firefox 2.0.0.2
Operating System: Mac OS X (10.4)

Hi,

The easiest way:

set s to “{10, 20, 30, 40}”
set l to run script s

gl,

Hi, grzessnik.

This does what you’ve described. It uses ‘run script’ to compile your string representation of a list into an actual list:

set txtData to "name1, {10, 20, 30, 40}
name2, {30, 30, 10, 50}
name3, {40, 30, 20, 20}
name4, {50, 10, 50, 10}"

-- Get a list of the text's paragraphs.
set mainList to txtData's paragraphs

set astid to AppleScript's text item delimiters
-- This assumes that the first comma in the paragraph delimits the end of the required string.
set AppleScript's text item delimiters to ", "

-- Turn each paragraph in the list into a sublist.
repeat with thisPara in mainList
	set thisPara's contents to {text item 1 of thisPara, run script (text from text item 2 to -1 of thisPara)}
end repeat

set AppleScript's text item delimiters to astid

mainList
--> {{"name1", {10, 20, 30, 40}}, {"name2", {30, 30, 10, 50}}, {"name3", {40, 30, 20, 20}}, {"name4", {50, 10, 50, 10}}}

Would you explain how that works, Mr. G?? :rolleyes:

Er, yes. Sorry if it wasn’t clear. :slight_smile:

The variable ‘txtData’ would normally be set to the text read from grzessnik’s text file:

‘mainList’ is initially set to a list of txtData’s paragraphs, namely:

AppleScript’s TIDs are then set to ", " in order to pick out text items delimited by that value. In the repeat, ‘thisPara’ is a reference to each slot in turn of ‘mainList’. Each slot initially contains a paragraph, but this is replaced in the list with a two-item list containing the first text item of the paragraph and the result of applying ‘run script’ to the rest of it. So, when the value of ‘thisPara’ is ‘item 1 of {“name1, {10, 20, 30, 40}”, “name2, {30, 30, 10, 50}”, “name3, {40, 30, 20, 20}”, “name4, {50, 10, 50, 10}”}’:

Thanks, Nigel. I understood all but the “run script” functionality. As I see and play with it, run script “{1, 2, 3, 4}” simply removes the quotes, and leaves a proper AppleScript list which I’ve not been able to find an alternative way of doing other than to parse it. Neat. :wink:

Yes, it’s just creating the list at runtime

Gotcha, Stephan – can this be done to create records as well?

Of course,

here a modified version of Nigel’s script with records

set txtData to "name1, {a:20, b:40}
name2, {a:30, b:50}
name3, {a:30, b:20}
name4, {a:10, b:10}"

-- Get a list of the text's paragraphs.
set mainList to txtData's paragraphs

set astid to AppleScript's text item delimiters
-- This assumes that the first comma in the paragraph delimits the end of the required string.
set AppleScript's text item delimiters to ", "

-- Turn each paragraph in the list into a sublist.
repeat with thisPara in mainList
	set thisPara's contents to {text item 1 of thisPara, run script (text from text item 2 to -1 of thisPara)}
end repeat

set AppleScript's text item delimiters to astid

mainList
--> {{"name1", {a:20, b:40}}, {"name2", {a:30, b:50}}, {"name3", {a:30, b:20}}, {"name4", {a:10, b:10}}}

Thanks, Stefan – I’ve used “run script” to run a script, but had not known of this mode of operation. A way to build a record as text and insert it into a script. I like it.

The operation is, in fact, to compile and run the script in the string and to return the result. Although the script in this case is only a value, it still returns a result when run, as does this if you run it in Script Editor:

{a:20, b:40}

Thank you Mr. G - somehow in my travels, I had missed that nuance. Your first script was clear; it was my understanding of the operation that was not.

Thank you so much.
It is simple thing, I’ve done this other, harder way.

I understand this code. I don’t know only what this script is. It is AS function or something?

I see the light on my way :smiley:

Regards

Suppose you had a compiled AppleScript in your Scripts Folder called myScript.scpt, and you wanted to call it from another AppleScript. You could do this:

run script ((path to scripts folder from user domain as text) & "myScript.scpt")

and it would run.

Or, suppose you composed a script as text:


set aTest to "-- This is a test" & return & "display dialog \"Hi There\" buttons {\"Hi\"} default button 1" & return & "beep 3"

run script aTest

with the same result as compiling and running the text in aTest.

What I hadn’t known was that you can have a single AppleScript object like your list: “{12, 13, 14}”, and running it as a script:

set myList to run script "{12, 13, 14}"

and the quoted list, which you can manipulate and prepare by other means, or get from a document, becomes an AppleScript object assigned to your variable myList.

The reason I asked about records, is because this presents a means of “building” a record:

set R to "{"
repeat 3 times
	set N to text returned of (display dialog "Please enter a unique name" default answer "")
	set X to text returned of (display dialog "Please enter a unique number" default answer "")
	set R to R & N & ":" & X & ", "
end repeat
set R to text 1 thru -3 of R & "}"

(*Suppose I answered: Abel, 34, Ben, 26, Cathy, 29, and then ran the script below

set tRec to run script R
get tRec's cathy as number

→ 29, from a record built at run time without knowing the names in advance.

Thanks for explanation.

It’s so helpful function.

My work gets harder :). Time for next step.

Hi Adam,

It’s easier to pass the field value as a paremeter of ‘run script’. e.g.


display dialog "Enter the record label:" default answer ""
set the_label to text returned of result
set the_value to {1, "hello", {"dog", "cat"}}
set the_rec to run script "on run p
set v to item 1 of p
return {" & the_label & ":v}
end run" with parameters {the_value}

gl,

Didn’t know that, Kel; Thanks :wink: