Notifications
Clear all

[Closed] quickly find duplicated names in array of objs

if you want to use a “linear” cull with the sorted hash array it can be done like this

strings = #("grandad", "table","immutable","mutable","immutable","Dictionaries","Vectors","Dictionaries","Vectors",
   			"mutable","immutable","Dictionaries","Vectors","Dictionaries","Vectors", "happy go lucky")
   
   fn sortcomparefn i j values: =
   (
   	v1 = values[i]; 
   	v2 = values[j];
   	if v1 < v2 then 1 else if v1 > v2 then -1 else 0;
   )	
   
   fn CopyUnique indices hashes =
 (
 	unique = #();
 	unique.count = indices.count;
 	j = 1;
 	unique[j] = indices[j];
 	for i = 2 to indices.count where hashes[unique[j]] != hashes[indices[i]] do
 	(	
 		j += 1;
 		unique[j] = indices[i];
 	)
 	unique.count = j;	
 	unique;
 )
   
   fn FindUniqueNotInABinaryStylee stringlist =
   (	
   	nStrs = stringlist.count;
   	
   -- hash the strings and create an indexing array the sort the indexes	
   	
   	hashedstrings =  for s in stringlist collect getHashValue  s 73856093;
   	indexes =  #{1..nStrs} as array;
   	qsort indexes sortcomparefn values:hashedstrings;
   
   -- collect uniques using binary search,  collects a unique value or the first value in a run of duplicates 
   	
   	--for i = 1 to nStrs where i == bsearch i indexes sortcomparefn values:hashedstrings collect i
   		
   	CopyUnique indexes hashedstrings;
   )	
   
   uniques = FindUniqueNotInABinaryStylee strings;
   duplicates = (#{1..strings.count} - uniques as bitarray) as array;

but I doubt it will win much over the binary search, I wouldn’t be surprised if the bsearch variation is faster.

This simple solution worked for me. it finds duplicate names, stores them in an array, then appends duplicate named ones with a random number string.

uniques = #()
dups = #()
for i in selection where not (appendifunique uniques i.name) do appendifunique dups i
clearselection()
select dups
for i in dups do i.name = i.name+"_"+random 1 10000 as string

It is not safe to use random if you want to get unique names exactly.
We’ve discussed several times how to make a unique name while keeping it simple. The best solution is to use the built-in uniqueName method.

The script might be as:

fn makeUniqueName name trim:"_0123456789" post:"" numDigits: = 
(
	_name = trimright name trim 
	uniqueName (_name + post) numDigits:numDigits
)

Very cool. That’s why communites are awesome, always helpful info!.

Thanks!

Page 2 / 2