Grouping elements which share common parts of a string

I want to compare two lists and find matches based on the numbers in the first list. In all cases, the first digits in the numbers in the second list will match the ones in the first list as shown in the image below. In this case, the numbers are element IDs. I’d like to group the matches and then apply a parameter value to each group. The part I’m struggling with is grouping the elements based on the common numbers since the number of characters differ. Can someone please point me in the right direction?

list

String.Contains, cross product lacing.
List.FilterByBoolMask with levels applied correctly.

2 Likes

Thank you, I’ll give that a try!

Jacob, I added the String.Contains node as you suggested, but am unclear about what I need to do next. I think I’m close but need some help crossing the finish line. A more thorough explanation of what I’m trying to accomplish might help. What I am trying to do is take a parameter value from a group of “Parent” elements and apply the same value to a group of “Child” elements. In my case, I’m using element IDs to to build a relationship between the Parents and Child elements. For the parent elements, I’m simply writing the element ID to a shared parameter. For the Child elements, I’m concatenating the element ID of the Parent element with the Element ID of the Child element (with an underscore between the two) and writing that to a shared parameter. (These values are being applied in a separate script.) So, in the image below you can see I have a list of Parent and Child elements showing their IDs. You can see that the first set of digits of the Child elements correspond to element IDs of the Parent elements. The idea here is that I want to control a parameter value of many elements by only changing the parameter value of a single element. If anyone could help me with this, I’d truly appreciate it. If you have any questions or want to see more of the script, let me know.

Thank you, Jason

I’ll reach out by PM if that’s ok wth you.

Hi @Jason_Seck,

I recently had the same challenge, of moving loads of parameter values from a parent family to all their respective child families.

I set up this workflow for my colleague:

image

Python Script:

import clr
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
    
doc = DocumentManager.Instance.CurrentDBDocument

bool = IN[0]
elem = []

if isinstance(IN[1], list):
	elem = UnwrapElement(IN[1])
else:
	elem = [UnwrapElement(IN[1])]
	
param = IN[2]

output = []

#Transaction start:
TransactionManager.Instance.EnsureInTransaction(doc)
if bool == True:
	
	for i in elem:
		p = i.LookupParameter(param).AsString()
		subids = i.GetSubComponentIds()
		
		subElements = []
		try:
			for j in subids:
				elements = (doc.GetElement(j))
				ep = elements.LookupParameter(param).Set(p)
				subElements.append(ep)
		
			output.append(subElements)
		except:
			pass

else:
	output.append('Set bool to true')	
#Transaction end:
TransactionManager.Instance.TransactionTaskDone()		

OUT = output

From Generic Model Parent:

To Parking Child:

1 Like

Martin, thank you for offering your solution. I was able to get mine to work with some help from Jacob using all out of the box nodes. Python is a little over my head at this point, but is something I need to learn.

That’s super, Jason. I realize my solution wasn’t quite what your post was actually about, but I thought I’d share it afterall since I’d just encountered the same obstacle :-).

Anyways, good to hear you guys figured it out.
Perhaps you should share the solution for future references? :slight_smile:

Jacob is going to share the solution he came up with. Stay tuned.

I’ve been very busy with unexpected customer issues today - sorry for the slower public share.

Hopefully this image will provide clarity on my initial post:

1 Like