How do I filter list of elements by 2 parameters at once?

I want to number elements on my schedule using a parameter called “Mark” so that different objects get different number from 1…x (x=how many objects are on schedule).

I have selected a list of all the elements used in this schedule and want to sort it by parameters “Family and Type” and “L” in a way that:
Elements that match both of these parameters with each other will receive same “Mark” value but objects that do not share both parameters will receive different value.

Can’t seam to find a thread for this or figure it out myself so thanks in advance for any help.
Also don’t mind “L” parameter having blank cells.

If you want the schedule to show a specific group of elements by Family and Type, then use either the “equals” or “contains” filtering option and input a specific value in the value field. Then filter the parameter L using “is greater than” and leave the value field blank. Or you can filter both parameters with the “is greater than” and blank value to show all elements that have a value in both parameters.

image

The easiest way to do this would be a forloop in python. you can even use x=x+1 in your loop to give you a list of marks as well. I could probably show you how but Im a pretty sloppy coder so whatever I would write off the top of my head would need some debugging.

Since this was posted as a Revit question, I assumed @1bitBoolean wasn’t wanting to use Dynamo to modify the schedule. I probably should have verified that up front and directed the question to be posted on the Revit forum, instead of just answering willy-nilly. My bad!

Not entirely sure what you’re after here, but I think you can try this (no Python required):

  1. Get the selected elements. Not sure how you want to do this but it is worth noting that you’ll want them in a one dimensional (flat) list.
  2. Use an Element.GetParameterValueByName node with the element set to level one, the parameter names at level two, and lacing to longest.
  3. Join the pairs of values into a single string with a String.Join node. You can use any intermediate value between the two, no need to be specific unless you want this in the mark.
  4. Use a List.GroupByKey node to group all the elements (step 1 is the list) by the joined string (step 3 is the key).
  5. Sort the sublists using a List.SortByKey if you want the values in order, but you can skip this if you don’t care about the order.
  6. Develop the mark value by either building a list from the start value to the number of keys in the sort by key list, or by using the keys themselves. A code block like 0..List.Count(n); could go a long way here.
  7. Use a Element.SetParameterValueByName node to drive the mark value for the items in each group (step 5, unless you skipped that in which case step 4) to the mark developed in step 6. Make sure the list levels are step 2 for the elements and step 1 for the value, with longest lacing.
2 Likes

I apologize for the confusion, this is in fact a dynamo question. I am trying to number elements where elements that match both “Length” and “Family and Type” receiving the same index (“Mark” parameter) while others all get an unique value.

I followed @jacob.small 's instructions but something doesn’t seem right.

Check step two. Need a list of parameter names and a list of elements.


I am not sure where to plug in the parameter node

That node should have a list of parameter names, not a combined string. The string.join happens after the get parameter value by name.


Alright, got it, what pairs of values do I need to join?

Ah! Family and type is an element; means we need to take a slightly different path.

Feed just the “Family and Type” parameter name into the Element.GetParametervalueByName node and reset the lacing and list levels. Then use a Element.Name node to pull the name of each family/type.

Then use another Element.GetParameterValueByName node to get the 'Length" from the flattened list (from step 2). Then use a String.FromObject node to convert the values to strings.

Now use a List.Create node to join the results of the Element.Name node and the results of the String.FromObject node.

Then the String.Join node where the first string is the results of the Element.Name node and the second is the results of the String.FromObject node.

We can then pick up on workflow as we had before.


Slowly getting there, still a bit lost in the keys part

Can you expand the preview data of the String.Join?

Ok - let’s replace the String.Join with the following code block:

elementNames + separator + lengths;, and use a string of " - " as the separator.

That should give you something like “45x45 Int. Lath - 340” for each family. That will become the key. for the group by key.

The List.SortByKey will take the groups and uniqueKeys outputs from the List.GroupByKey node.

It works! Thank you so much.
Posting finished node tree in case someone needs this in the future:

1 Like