Confused With Loops

Hi Knimers,

I am dealing with a data set involving Groups, Nested groups and its users basis the domain name. I am trying to create a linear data basis the Groups. Attaching the sample input table and desired output

Output Table

This exercise involves extracting all the users including users of nested group for that particular master group and creating linear data.
Logic is - Filter GroupName (Cat) > TypeofEntity (check for “Group” eg Big Cat) > Search for group BigCat in Group Name from input table and add all users and groups to Data set “Cat” and repeat until all groups in Col TypeOfEnity is covered for Master Group Cat.

I tried to build using Table row to variable loop start nodes. I am unable to find a better approach, please help.

Regards
Suhas

Why is the 5th row missing in the Output Table?

Logic is - Filter GroupName (Cat)

Does this mean that you’re filtering for GroupNames that equal “Cat” ? Or are you filtering for GroupNames that contain “Cat”? Where is the filtering criteria coming from?

Can you explain your thinking behind wanting to use a Table Row to Variable Loop for this?

It seems to me that it would be simpler to just assign a new GroupName “Cat” to any row whose GroupName contains the word “Cat”. Is there something I’m missing?

Hello @Suhas27
Maybe the Group Loop Start Node can help you. By configurate the Group Column with your “GroupName” column the Group Loop Start Node filters all rows fist with " Big Cat", then with “Medium Cat”, “Cat” etc. what your content is in this column. By using a Case Switch you can can do specific operations with this grouped tables.

Regards,
Brotfahrer

@elsamuel

5th row is missing because groupdomain name for Big cat in Master group “Cat” is America only. So i need users and nested group only for America domain.
No i am not filtering the group name only Cat. The group can be anything.
What i need is all users of nested groups for the Master group Cat. Users in subgroups should be extracted and joined with master group Cat and this process goes on until all the Groups in col “Type of Entity” is extracted for master group Cat.

So i need to run loop on TypeOfEntity column and extract users and join and then move on to new GroupName.

@Brotfahrer

Just trying to be more specific .
Step 1 - Filter group name “Cat” from GroupName col.
Step 2 - Check if Type of Entity is Group for any row. eg “BigCat”
Step 3 - If yes, find all the rows for that sub group “BigCat” in Col “GroupName” again and join with Group “Cat” for that particular GroupDomain
Step 4 - Then again look for TypeOfEnt “Group” in rows filtered for GroupName “Big Cat”.
Step 5 - If yes, find all the rows for that sub group “Medium Cat” in Col “GroupName” again and join with Group “Cat” for that particular GroupDomain
Step 6 - So keep running this until all the users and groups are extracted for group “Cat” and create linear data for Group “Cat”. This is one bunch of data for “Cat”

So for Cat - instead of just 3 rows , now you have 10 rows after extracting all nested groups also.

Regards
Suhas

@Suhas27

sorry, I don’t understand this logic. The difference I see between the example inout and output table is that “Big Cat” and “Medium Cat” is replaced by “Cat”. Could it be that the example input table dosen’t have the right form?
If I understand your question right the output table has more rows and some cells should have some missing values.

Regards,
Brotfahrer

@Brotfahrer

Sorry, The group name is not replaced, the output table is list of all users and groups falling under GroupName “Cat” after unwinding all the nested groups. The output table is result of performing exercise only for first group “Cat” and some rows are missing because of different domain in nested group.

Regards
Suhas

It’s still unclear what you’re trying to do.

Do you have a graphic that illustrates what these groups and domains and nested groups are and how they relate to each other?

Where is the data in the input table coming from?

Seems like a hierarchical problem where the structure needs to be flattened, so instead of child-parent relations everything should go in one level. Additionally, the GroupDomain has to be filtered so that the children match the GroupDomain of the parents TypeOfEntity.
I have a working solution in mind, but it currently does not work with multiple Groups per level. I’ll think about it a bit longer and post it soon. Recursion is indeed confusing. :wink:

Ok, this looks nothing like what I had in mind.

  1. configure workflow via component. (prevents typos)
  2. recursive loop start. in the first iteration it will pass through its input table, later it will pass the bottom input of the loop end node. those two cases are handled with a Java IF Node
  3. top branch - first iteration: filter GroupName of data sample by user input
    overwrite GroupName by user input and pass to top input of loop end (final output)
    filter to include only entity of type “Group” and pass to bottom input of loop end (pass back to loop start) - this is used to find all rows of the child elements of the previous iteration.
  4. bottom branch - later iterations: get list of parent rows from previous iteration to loop over them
    filter GroupName by name of parent (EntityName of previous iteration) and GroupDomain of parent
    overwrite GroupName by name of parent and pass to top input of loop end (final output)
    filter to include only entity of type “Group” and pass to bottom input of loop end for next iteration

Things to look out for:

  • The loop end conditoins might not work for the actual data set. Different settings might be required.
  • I did not optimise it in any way. The initial table gets passed to the row filters every thyme, which might get slow for big tables.


recursive loop.knwf (80.6 KB)

2 Likes

@Thyme

This solution proposed by you worked perfectly for me. Thanks.
When i downloaded this WF, there is also a Cache node used, which i am unable to understand. And What exactly is the Java if function here ? If not based on iteration, is there any other condition or criteria i can use the If node ?

Also, if it was left to me alone, i would never think of using “If” nodes. Where can i learn about such useful nodes ?? and Its use cases ?

Thanks
Suhas

It seems I forgot to export the workflow before uploading. The Cache node was supposed as placeholder, but I figured out it is not needed and the Row Filter can be connected to the Java IF directly, just as shown in the screenshot. I uploaded the WF again.

The Cache node writes the incoming table to disk, caching it. It can be useful in big workflows, I like to use it as node that does no manipulation.

The Java IF activates the upper output in the first iteration (to initialise the loop), later it activates the lower output. Any other IF node would require a proxy flow variable to control the outputs.

If you want to find more of such nodes, you can have a look at the “Workflow Control” section in the node repository. Various IF nodes can be found in the Switches group, along with Case Switches. Error handling and Automation might be interesting as well.
Unbenannt
recursive loop.knwf (75.4 KB)

1 Like

Oh I will edit my workflow.
Instead of Component, i have used group loop node and made few small edits to the workflow to suit my data set. It worked well.
Thanks again for your help here.

@Thyme

I have a question. In the Java If node, the return value for condition is either 0 or 1. How does this work.
Sorry, i have a no technical knowledge on java here.

Yes, that’s because the allowed output is either 0 (activate top output) or 1 (activate bottom output). You can find that in the node description.

The Flow Variable “current iteration” is generated by the loop start node and keeps track of the current loop number. It starts with 0 in the first round/iteration and gets bigger by 1 each iteration. When this Flow Variable “current iteration” is equal to 0, the code snippet returns 0, activating the top output. This happens only in the first iteration.
When “current iteration” is not 0, the snippet returns 1, activating the bottom output. This happens in all the other iterations.

One could also write it this way. It’s the same thing as in the node:

if ($${IcurrentIteration}$$ == 0) {
	return 0;
}
else {
	return 1;
}
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.