Convert number string to list

-- How would I convert text results of an SQLite query to a list of numbers?

-- String returned from SQLite looks like this:
set numberText to "791
917
185"

-- What I want to see is a list of numbers:
set numberList to {791, 917, 185}

-- I can easily convert the list to the string:
set text item delimiters to return
numberList as string

-- Now I want to do the opposite, convert the numbers to a list. These do not work:

numberText as list
items of numberText
text items in numberText
items of numberText as list
list items of numberText


-- Even ths old hack does not work:
do shell script "echo " & numberText & " | sed 's|" & return & "|,|g' "
do script "{" & result as string & "}"


-- Is there a easy way to do it without resorting to an item-by-item loop?

2.4 MBP, Mac OS X (10.6.3)

Posted on May 31, 2010 7:07 AM

Reply
3 replies

May 31, 2010 9:00 AM in response to Gnarlodious

There's no way (AFAIK) to convert a list of strings to a list of integers en masse, but there are a couple of suggestions I have.

First off, it's trivial to convert the text into a list of items via something like:

set numberText to "791
917
185"

set numberList to words of numberText


This will break the text into a list of text objects, like:

--> {"791", "917", "185"}


but, of course, these are text objects, not integers. For that I have two suggestions.

One is a simple loop like:

repeat with i from 1 to count numberList
set item i of numberList to (item i of numberList as integer)
end repeat


This very quickly iterates through the list and coerces the item items into integers (although you might want to add some error checking to make sure they're all valid integers).

The second option doesn't bother, and relies on either AppleScript's automatic coercion, or you coerce to an integer at runtime. For example, this code uses AppleScript's automatic coercion:

repeat with i from 1 to count numberList
if 600 < item i of numberList then
display dialog "Got " & item i of numberList
end if
end repeat


This relies on the fact that when you run a comparison between two objects such as an integer (600) and a text item (item i of numberList, which is a text item), AppleScript will coerce the second item to the same class as the first item.

In this variation, you explicitly coerce the value before comparing:


repeat with i from 1 to count numberList
if (item i of numberList as integer) > 600 then
display dialog "Got " & item i of numberList
end if
end repeat


in this case the item from the list is explicitly coerced to an integer before comparing, so it avoids the (trivial) overhead of the loop.

In both cases you should add some error checking to make sure the 'text' can be coerced successfully.

The practicality of the three options depends largely on what you're doing with the data, so I'll leave you to decide which path to take.

May 31, 2010 1:03 PM in response to Gnarlodious

Hello Gnarlodious,

Well, I wonder what is the problem with using simple loop?

Loop is the simplest and the cleanest way to do it.

--CODE 1
set t to "791
917
185"
set nn to {}
repeat with p in t's paragraphs
set end of nn to 0 + p
end repeat
return nn -- {791, 917, 185}
--END OF CODE 1


You can even define a Perl-like map() handler for processing list if it helps.

--CODE 2
set t to "791
917
185"
return map(asNumber, t's paragraphs) -- {791, 917, 185}
on map(func, aa)
script o
property xx : aa's contents
property yy : {}
property f : func
repeat with x in my xx
set end of my yy to my f(x's contents)
end repeat
return my yy's contents
end script
tell o to run
end map
on asNumber(t)
t as number
end asNumber
--END OF CODE 2


---
If you really want, 'run script' osax can do the conversion at once -

--CODE 3
set t to "791
917
185"
return run script ("{" & list2text(t's paragraphs, ", ") & "}") -- {791, 917, 185}
on list2text(aa, delim)
set astid to a reference to AppleScript's text item delimiters
set astid0 to astid's contents
try
set astid's contents to {delim}
set t to "" & aa
set astid's contents to astid0
on error errs number errn
set astid's contents to astid0
error errs number errn
end try
return t
end list2text
--END OF CODE 3


But it is not at all recommendable because -
a) it is much slower than loop methods; and
b) it has serious security hole and can be very dangerous (as shown in CODE 3a below)

--CODE 3a
set t to "791
917
display dialog "hello"
185"
return run script ("{" & list2text(t's paragraphs, ", ") & "}")
on list2text(aa, delim)
set astid to a reference to AppleScript's text item delimiters
set astid0 to astid's contents
try
set astid's contents to {delim}
set t to "" & aa
set astid's contents to astid0
on error errs number errn
set astid's contents to astid0
error errs number errn
end try
return t
end list2text
--END OF CODE 3a


Hope this may help,
H

Message was edited by: Hiroto

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Convert number string to list

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.