I’m hugely embarassed that I haven’t got a clue how to do this…

I have a simple list of numbers, and want to insert additional numbers in the list in strict sequence:

e.g.

set _list to {2, 5, 9}

–set new_list_entry to 1 – Example A
–set new_list_entry to 6 – Example B

… and of course I’d like the result to be:

Example A: {1, 2, 5, 9}
Example B: {2, 5, 6, 9}

I’ve tried a few repeat loops involving if < or > then, and I made a (perfunctory) search of the forum, but can’t seem to wrap my head around this very simple logic.

(Don’t blame it on the turkey, I had Kung Pao Pork tonight.)

If someone would oblige, vanilla AS in terms I can understand is preferred.

Thanks Much.

Peter B.

Hi Peter,
This was harder than I thought also. I’m still testing my code below but maybe you can run some tests and see if it works for you. Some of the cleverer guys may have a better solution but please give this a try for now!

``````set no_list to {2, 5, 9}

set new_list_entry to 3 -- Example A
--set new_list_entry to 6 -- Example B

repeat with i from 1 to the number of items of no_list
set this_no to item i of no_list
if new_list_entry < this_no then
set list_position to i
exit repeat
end if
end repeat

set new_list to {}
repeat with i from 1 to the number of items of no_list
set this_no to item i of no_list
if i = list_position then
set this_no to new_list_entry & this_no
else
set this_no to this_no
end if
set new_list to new_list & this_no
end repeat

choose from list new_list
``````

Nik

Hi,

try this

``````set no_list to {2, 5, 9}

set new_list_entry to 7 -- Example A
--set new_list_entry to 10 -- Example B

choose from list insert_list_item(no_list, new_list_entry)

on insert_list_item(L, newItem)
if newItem is in L then
return L -- doesn't insert, if the value is alread in the list
else if newItem < item 1 of L then
return newItem & L
else
repeat with i from 2 to count L
if newItem < item i of L then return (items 1 thru (i - 1) of L) & newItem & (items i thru -1 of L)
end repeat

if newItem > last item of L then
return L & newItem
else
return (items 1 thru -2 of L) & newItem & last item of L
end if
end if
end insert_list_item
``````

I think I’d just go for appending and sorting:

``````set oldList to {2, 5, 9}
set NL to {}

set NL's end to sort(oldList & N)
end repeat

NL --> {{1, 2, 5, 9}, {2, 5, 6, 9}}

to sort(sortList)
script L
property srt : sortList
end script
tell (count L's srt) to repeat with i from (it - 1) to 1 by -1
set s to (L's srt)'s item i
repeat with i from (i + 1) to it
tell (L's srt)'s item i to if s > it then
set (L's srt)'s item (i - 1) to it
else
set (L's srt)'s item (i - 1) to s
exit repeat
end if
end repeat
if it is i and s > (L's srt)'s end then
set (L's srt)'s item it to s
end if
end repeat
return L's srt
end sort
``````

Thank you all very much for the examples… I should be able to adapt one or the other to work.

The example I provided was in simplest possible form. I will need to work with numbers higher than 10, so StefanK’s solution (and the nice added feature of excluding existing numbers) looks like it might work better for me.

I will probably only be adding one number at a time to an existing list, so Adam’s ‘append and sort’ may not be necessary… but you never know.

I have multiple tab delimited text files of an auto parts inventory with hundreds of existing entries to which I’d like to add more… in proper sequence. Your help should make that possible. I hope I can work out the rest of the needed details… but I’ve never done much scripting with lists, and trying to work out the insertion would have beaten me to death… literally.

Thanks Again.

Peter B.

If you’re dealing with lists that must be kept in correspondence (that is a sort of several based on an insertion in one must keep the others in the same order) there are neat ways of doing that.

I should be paying for this…

I was dead wrong. Even with the examples provided this morning, I still can’t put this all together on my own. The finer details have stumped me too.

I hope it’s clear from the code and comments below what I’m trying to do.

(StefanK: You may recognize your handler at the end of my own mess. Now that I think of it, replacing an existing entry might actually be useful when {e.g.} a quantity or a price change occurs.)

I’m getting closer, anyway… up next is the ‘front end’.

Thanks.

Peter B.

``````

tell application "Finder"

set new_entry to "0418043	2.75	2	\$5.50"
--set new_entry to "0418078	3.50	4	\$14.00"

set new_entry_value to word 1 of new_entry as number

set read_data to "0418044	2.49	1	\$2.49
0418045	2.47	2	\$4.94
0418055	2.25	15	\$33.75
0418058	3.21	1	\$3.21
0418063	2.61	1	\$2.61
0418065	4.28	1	\$4.28
0418066	2.10	15	\$31.50
0418068	5.40	1	\$5.40
0418069	2.98	1	\$2.98
0418072	2.75	1	\$2.75
0418074	2.19	15	\$32.85
0418075	2.52	5	\$12.60"

set entry_values to {}

repeat with paragraph_n in paragraphs of read_data
set entry_value to word 1 of paragraph_n as number
set entry_values to ((entry_values) & entry_value) as list
end repeat

set numeric_inventory to my insert_list_item(entry_values, new_entry_value)

-----

--Begin pseudo code... a failed shot in the dark...

-- The object here is to replicate format of read_data with complete new entry paragraphs included... *without* multiple duplication of existing entries...

set inventory_output to ""

repeat with this_value in numeric_inventory
if this_value is in read_data then
repeat with paragraph_n in paragraphs of read_data
set inventory_output to inventory_output & paragraph_n & return
end repeat
else
set inventory_output to inventory_output & new_entry & return
end if
end repeat

--End pseudo code...

-----

set amended_inventory to (desktop as text) & "Amended Inventory.txt"

try
open for access file amended_inventory with write permission
set eof of file amended_inventory to 0
write inventory_output to file amended_inventory starting at eof
close access file amended_inventory
on error
close access file amended_inventory
end try

open file amended_inventory

end tell

-----

on insert_list_item(entry_values, new_entry_value)
if new_entry_value is in entry_values then
return entry_values -- doesn't insert, if the value is already in the list
else if new_entry_value < item 1 of entry_values then
return new_entry_value & entry_values
else
repeat with i from 2 to count of entry_values
if new_entry_value < item i of entry_values then return (items 1 thru (i - 1) of entry_values) & new_entry_value & (items i thru -1 of entry_values)
end repeat

if new_entry_value > last item of entry_values then
return entry_values & new_entry_value
else
return (items 1 thru -2 of entry_values) & new_entry_value & last item of entry_values
end if
end if
end insert_list_item

-----

``````

I guess I don’t understand, Peter.

1. You have an existing text list that is both tab and return delimited (spreadsheet?)

2. You want to add a new line. In your workflow, how will you choose the number? You could choose from alist showing all the missing numbers in the existing list.

``````set read_data to "0418044		2.49	1	\$2.49
0418045	2.47	2	\$4.94
0418055	2.25	15	\$33.75
0418058	3.21	1	\$3.21
0418063	2.61	1	\$2.61
0418065	4.28	1	\$4.28
0418066	2.10	15	\$31.50
0418068	5.40	1	\$5.40
0418069	2.98	1	\$2.98
0418072	2.75	1	\$2.75
0418074	2.19	15	\$32.85
0418075	2.52	5	\$12.60"

set rdList to paragraphs of read_data

set nums to {}
repeat with N in rdList
set end of nums to (word 1 of N) as number
end repeat

-- assuming the numbers are in order (sorted) then
set wee to item 1 of nums
set big to item -1 of nums
set available to {}

repeat with k from wee + 1 to big - 1
if k is not in nums then set available's end to "0" & k
end repeat
--> the list of missing numbers
``````
1. If the number picked without benefit of the available numbers and is already in the list, the best thing would be to choose one nearby if position in the list means anything. Otherwise why not just add it to the end or beginning?

2. The way to deal with reconstructing the tab/return text list is to do it by insertion in the AppleScript list and then use text item delimiters to reconstruct the paragraphs.

``````to insertInList(myList, Insertion, AfterNum)
if AfterNum â‰¥ (count of myList) then
set end of myList to Insertion
return myList
end if
tell myList
set frontPart to items 1 thru AfterNum
set backPart to items (AfterNum + 1) thru -1
end tell
set myList to frontPart & Insertion & backPart
return myList
end insertInList
``````

Thanks again… yes, the existing inventory is in text form… as exported from a Windows Excel spreadsheet.

I may be approaching the problem in the wrong way… and maybe asking about it in the wrong way as well. In my last script example, the two new sample entries were carelessly selected… as needing to be added at the beginning or the end of the existing list.

I will also need to add entries that are between numeric values in the list:

set new_list_entry to “0418047 1.05 2 \$2.10”

set existing_list to “0418044 2.49 1 \$2.49
0418045 2.47 2 \$4.94
0418055 2.25 15 \$33.75
0418058 3.21 1 \$3.21”

… so that the resultant list becomes:

0418044 2.49 1 \$2.49
0418045 2.47 2 \$4.94
0418047 1.05 2 \$2.10
0418055 2.25 15 \$33.75
0418058 3.21 1 \$3.21

The ‘front end’ for new entries I already have working…

(I hesitate to add this because it may only confuse the issue further. Each set of new entry values are entered in an HTML form, then passed to a target script {the one I’m working on} via Missing Link.)

The target script parses out the values and sets them in tab delimited form:

set inventory_addition to part_num & tab & unit_cost & tab & stock_quan & tab & exten_value

… to create a new paragraph.

In the actual script, data is read in from the existing inventory list. I then need to insert the new paragraph entry into the list… in numeric sequence by part number. That’s the only remaining problem.

(The amended inventory is then spit out to a new file.)

StefanK’s script allowed me to insert a simple numeric value in an existing list of values and I thought I could take that result and make the full paragraphs of the list ‘follow suit’, as it were. But I’m still (obviously) struggling with that bit.

I guess I should spend some more time studying the examples I’ve already been given… maybe a light will finally go on.

If it ever does, I’ll post the final script.

Peter B.

A half an hour later… light in the forest !!!

Convoluted as it may be, I should be able to work with this.

Thanks again for all the help here. I’m very pleased.

Onnerds and upperds.

Peter B.

``````
global new_entry

tell application "Finder"

--set new_entry to "0418043	2.75	2	\$5.50"
set new_entry to "0418073	.45	8	\$3.60"
--set new_entry to "0418078	3.50	4	\$14.00"

set new_entry_value to word 1 of new_entry as number

set read_data to "0418044	2.49	1	\$2.49
0418045	2.47	2	\$4.94
0418055	2.25	15	\$33.75
0418058	3.21	1	\$3.21
0418063	2.61	1	\$2.61
0418065	4.28	1	\$4.28
0418066	2.10	15	\$31.50
0418068	5.40	1	\$5.40
0418069	2.98	1	\$2.98
0418072	2.75	1	\$2.75
0418074	2.19	15	\$32.85
0418075	2.52	5	\$12.60"

set existing_paragraphs to paragraphs of read_data

set entry_values to {}

repeat with paragraph_n in paragraphs of read_data
set entry_value to word 1 of paragraph_n as number
set entry_values to ((entry_values) & entry_value) as list
end repeat

set inventory_list to my insert_list_item(entry_values, new_entry_value)

set inventory_output to ""

repeat with this_entry in inventory_list
set inventory_output to inventory_output & this_entry & return
end repeat

set amended_inventory to (desktop as text) & "Amended Inventory.txt"

try
open for access file amended_inventory with write permission
set eof of file amended_inventory to 0
write inventory_output to file amended_inventory starting at eof
close access file amended_inventory
on error
close access file amended_inventory
end try

open file amended_inventory

end tell

-----

on insert_list_item(entry_values, new_entry_value)
set existing_paragraphs to paragraphs of read_data
if new_entry_value is in entry_values then
return existing_paragraphs -- doesn't insert, if the value is already in the list
else if new_entry_value < item 1 of entry_values then
return new_entry & existing_paragraphs
else
repeat with i from 2 to count of entry_values
if new_entry_value < item i of entry_values then return (items 1 thru (i - 1) of existing_paragraphs) & new_entry & (items i thru -1 of existing_paragraphs)
end repeat

if new_entry_value > last item of entry_values then
return existing_paragraphs & new_entry
else
return (items 1 thru -2 of existing_paragraphs) & new_entry & last item of existing_paragraphs
end if
end if
end insert_list_item

-----

``````

Five minutes later…

I spoke too soon, but I think I can iron out the kinks.

I’ll post a final script when I get it right.

Peter B.

The only (apparent) remaining problem with my last posted script was when a new entry had a numeric value less than an existing inventory entry.

This version fixes that. There may yet be other bugs, but I’ll quit ‘bugging’ the BBS for now…

Thanks yet once more.

Peter B.

``````

global new_entry

tell application "Finder"

set new_entry to "0418043	2.75	2	\$5.50"
--set new_entry to "0418073	.45	8	\$3.60"
--set new_entry to "0418078	3.50	4	\$14.00"

set new_entry_value to word 1 of new_entry as number

set read_data to "0418044	2.49	1	\$2.49
0418045	2.47	2	\$4.94
0418055	2.25	15	\$33.75
0418058	3.21	1	\$3.21
0418063	2.61	1	\$2.61
0418065	4.28	1	\$4.28
0418066	2.10	15	\$31.50
0418068	5.40	1	\$5.40
0418069	2.98	1	\$2.98
0418072	2.75	1	\$2.75
0418074	2.19	15	\$32.85
0418075	2.52	5	\$12.60"

set existing_paragraphs to paragraphs of read_data

set entry_values to {}

repeat with paragraph_n in paragraphs of read_data
set entry_value to word 1 of paragraph_n as number
set entry_values to ((entry_values) & entry_value) as list
end repeat

set inventory_list to my insert_list_item(entry_values, new_entry_value)

set inventory_output to ""

repeat with this_entry in inventory_list
set inventory_output to inventory_output & this_entry & return
end repeat

set amended_inventory to (desktop as text) & "Amended Inventory.txt"

try
open for access file amended_inventory with write permission
set eof of file amended_inventory to 0
write inventory_output to file amended_inventory starting at eof
close access file amended_inventory
on error
close access file amended_inventory
end try

open file amended_inventory

end tell

-----

on insert_list_item(entry_values, new_entry_value)
set existing_paragraphs to paragraphs of read_data
if new_entry_value is in entry_values then
return existing_paragraphs -- doesn't insert, if the value is already in the list
else if new_entry_value < item 1 of entry_values then
return (new_entry as list) & existing_paragraphs
else
repeat with i from 2 to count of entry_values
if new_entry_value < item i of entry_values then return (items 1 thru (i - 1) of existing_paragraphs) & new_entry & (items i thru -1 of existing_paragraphs)
end repeat

if new_entry_value > last item of entry_values then
return existing_paragraphs & new_entry
else
return (items 1 thru -2 of existing_paragraphs) & new_entry & last item of existing_paragraphs
end if
end if
end insert_list_item

-----

``````