Rename duplicates in a list

Hello forum, newbie here.

I’ve searched around to no avail, can’t find a solution to this.
Might be me entering the wrong search words… again newbie :slight_smile:

I have a list, say for example:
“Adam
Adam
Eve
Adam
Eve
Adam”

The Adam and Eve will be read from a list of 88 different names that may or may not be repeated a few times.
They are really the keys of a piano, so the list would read:
“C0
C#0
D0 etc…”
But I believe the code to be the same for 2 or 88 different names in the list.
If I’m wrong, stop me!

So.

I’m trying to get AppleScript to output a new list that looks like this:
“Adam_no1
Adam_no2
Eve_no1
Adam_no3
Eve_no2
Adam_no4”

I would want the Adams and Eves to keep their position in the list and to give them a number that indicates the number of times Adam has been found counting form the top.
The list could also look like, it that’s easier.
(I know how to get the number in fornt of the name :slight_smile: )
“1_Adam_no1
2_Adam_no2
3_Eve_no1
4_Adam_no3
5_Eve_no2
6_Adam_no4”

I’m not asking for a finished script but rather a nudge in the right direction.
My guess is that the “1_Adam” list is easier to sort.
But then again I have no clue in how to get the _no increment to the different Adams and Eves.

Any help would be appreciated.

Kind Regards,
Anders

I’ve included my suggestion below. It may be a bit slow if the source list is very long, although it could be made faster with some minor edits. With a list of 60 items, the timing result was 19 milliseconds.

set sourceList to "Adam
Adam
Eve
Adam
Eve
Adam"
set sourceList to paragraphs of sourceList
set sourceListCount to (count sourceList)
set newList to {}

repeat with i from 1 to sourceListCount
	if item i of sourceList > "" then
		repeat with j from 1 to sourceListCount
			set newName to item i of sourceList & "_no" & j
			if newName is not in newList then
				set end of newList to newName
				exit repeat
			end if
		end repeat
	end if
end repeat

set {TID, text item delimiters} to {text item delimiters, linefeed}
set newList to newList as text
set text item delimiters to TID

newList

The above script returns the following:

“Adam_no1
Adam_no2
Eve_no1
Adam_no3
Eve_no2
Adam_no4”

Thank you so much for your fast reply.
I will have a look at the script when I get home from work.
Try and work out what does what.

It takes me roughly 45-60 to do this by hand.
So this will, literary, make my day :slight_smile:
Again, thank you!
/Anders

Script works like a charm!
Again, thank you.

I’m thinking out loud.
-it counts all the names - sourceListCount (in this example “6”)
-if the name is bigger than “” it repeats from 1 to j (in this example 6)
i = Adam + “_no” & j – Adam_no1
-if the name Adam_no1 exists it goes back and tries with a new j value (up to 6)
or
-if Adam_no1 is a unique name it adds the name to the end of the list

Do I understand this correctly?

Kind Regards,

Anders

Your understanding is entirely correct. I would probably edit lines 2 and 3 just to clarify:

-it counts all the names - sourceListCount (in this example “6”)
-if the name is bigger than “” it repeats from 1 to sourceListCount (in this example 6)
-the new name = Adam + “_no” & j – Adam_no1
-if the name Adam_no1 exists it goes back and tries with a new j value (up to 6)
or
-if Adam_no1 is a unique name it adds the name to the end of the list

Thank you for clarifying.
I’m new to Applescript.
Wish I started learning scripting earlier, would have saved a lot of time :slight_smile:
/Anders

I decided to rewrite my script in post 2 using ASObjC. I had hoped to eliminate one or both of the repeat loops but couldn’t accomplish that. In the end, the two scripts are identical in their basic operation.

On testing with a list of 60 items, the timing result for the ASObjC script was 993 milliseconds. I retested the script in post 2 and that took 38 milliseconds. I did a line-by-line analysis to possibly identify a particular source of the ASOjbC script’s poor test results but couldn’t isolate one particular cause.

use framework "Foundation"
use scripting additions

set sourceText to "Adam
Adam
Eve
Adam
Eve" -- in testing this contained 60 paragraphs

set sourceText to current application's NSString's stringWithString:sourceText
set theDelimiters to current application's NSCharacterSet's newlineCharacterSet()
set sourceArray to (sourceText's componentsSeparatedByCharactersInSet:theDelimiters)
set sourceArrayCount to sourceArray's |count|()
set targetArray to current application's NSMutableArray's new()

repeat with i from 1 to sourceArrayCount
	repeat with j from 1 to sourceArrayCount
		set newName to current application's NSString's stringWithFormat_("%@_No%@", (item i of sourceArray), j)
		if (targetArray's containsObject:newName) as boolean = false then
			(targetArray's addObject:newName)
			exit repeat
		end if
	end repeat
end repeat

set targetText to (targetArray's componentsJoinedByString:linefeed) as text

Great answers.

I would just like to point out that the additional list (newList) can be omitted by replacing the elements of sourceList in place. This will give an almost imperceptible improvement in speed, but also save RAM memory. But the task here is simple, so my comment is at your discretion.

Thanks KniazidisR for looking at my scripts. I’ll give your suggestion a try.

FWIW, I did a quick comparison on a new Mac running macOS 12.0.1, and the margin was much tighter: 44ms vs 21ms.

Thanks Shane–that’s a surprising difference. Did you test with 60 paragraphs in sourceText or 5 paragraphs as shown in my post. If the former, I may have to update to Monterey.

With 60. But it was also a new MacBook Pro.

However, Cocoa scripting on Monterey is significantly faster. (It suffered quite a slow-down from about macOS 10.14.)

I watched a few YouTube reviews of the new MacBook Pro and that’s a spectacular computer.

I’ll wait for a few maintenance updates and then install Monterey. Normally I just stick with whatever is working well, but faster Cocoa scripting makes the change worthwhile.

The lure of fast Cocoa scripting was too much and I installed Monterey. It took about an hour–which included a 12 GB download–and a few settings were not retained but otherwise everything went well.

I reran my script from post 7 above (but with 60 paragraphs). Previously it had taken 993 milliseconds and with Monterey the timing result was 88 milliseconds. I’m a happy man. :slight_smile:

So the script would look like this?
(also omitting the set newList to {})
[AppleScript]
set sourceList to “Adam
Adam
Eve
Adam
Eve
Adam”
set sourceList to paragraphs of sourceList
set sourceListCount to (count sourceList)

repeat with i from 1 to sourceListCount
if item i of sourceList > “” then
repeat with j from 1 to sourceListCount
set newName to item i of sourceList & “_no” & j
if newName is not in sourceList then
set end of sourceList to newName
exit repeat
end if
end repeat
end if
end repeat

set {TID, text item delimiters} to {text item delimiters, linefeed}
set sourceList to sourceList as text
set text item delimiters to TID

sourceList[/AppleScript]
It’s working but I get the names of the original list as well as the renamed list.
I tried “set start of sourceList” but got an error.

Thanks all for your replies.
I’m learning a lot and they are all eyeopeners.
Regards,
/Anders