Zero-Touch MultiReturn adds new level to OUT list

Hi All,

I’ve created a zero-touch node that multiplies each number of the incoming list of lists by 2.
The resulting list has an extra rank (even if the rank node says it doesn’t)

any ideas why? how do I output a list of lists similar to the flatten node one?
I’m using the MultiReturn so I can change the name of the output port (unless there is another way)

[MultiReturn(new[] { "out" })]
public static Dictionary<string, object> test (List<List<double>> data)
{

foreach (var lst in data)
{
for (int i = 0; i < lst.Count; i++)
{
lst[i] *= 2;
}
			
}

return new Dictionary<string, object>
{
{"out", data }
};

}

hi @salvatoredragotta, try this way;

First, create a new list for your return value and another list for sub-list.

// return result
var myData = new List<List<double>>();
foreach (var lst in data)
{ 
    // sub-list for inner list
    var subList = new List<dobule>();

    for (int i = 0; i < lst.Count; i++)
    {
           double res = lst[i] * 2;
           subList.Add(res);
    }
    myData.Add(subList);
}
return myData;

*Note: your method statement (public …) still need to write, of course.

@jean you are not using the [MultiReturn(new[] { "out" })] in your code.

I tried this but it doesn’t work

		[MultiReturn(new[] { "out" })]
		public static Dictionary<string, object> test3(List<List<double>> data)
		{

			var myData = new List<List<double>>();
			foreach (var lst in data)
			{
				// sub-list for inner list
				var subList = new List<double>();

				for (int i = 0; i < lst.Count; i++)
				{
					double res = lst[i] * 2;
					subList.Add(res);
				}
				myData.Add(subList);
			}
			return new Dictionary<string, object>
			{
				{"out", myData }
			};
		}

how to keep the structure of original list of lists.For Example, look at the List.Replace node in the orchid package

@salvatoredragotta you dont need to use a dictionary to return a single output. It explains why you are seeing the additional rank; dictionaries are key value pairs, so if you use them to output your values, the extra rank is needed to store these pairs.

Just return your list and change your methods return type accordingly:

	public static List<List<double>> test3(List<List<double>> data)
	{

		var myData = new List<List<double>>();
		foreach (var lst in data)
		{
			// sub-list for inner list
			var subList = new List<double>();

			for (int i = 0; i < lst.Count; i++)
			{
				double res = lst[i] * 2;
				subList.Add(res);
			}
			myData.Add(subList);
		}
		return myData;
	}

Edit: looks like @jean already gave you the answer!

1 Like

@Thomas_Mahon I want to have a control on the name of the single output port. is there another way?

Do you mean the label of the output port of the node, or the key name in the pop-up watch window from below the node?

@Thomas_Mahon

image

@salvatoredragotta you simply need to add an XML documentation file to your build output. In VS click Project > Properties, click the Build tab then check the XML Documentation File setting.

Now add the XML tags above any public class members. If you triple forward slash above the member, you will automatically generate the necessary tags. To rename your output ports, use the returns name tag:

@erfajo method to name output ports will only work if you develop nodes using Dynamo’s NodeModel, whereas Zero Touch uses XML tags.

4 Likes

Thanks @erfajo! I managed to achieve what I wanted following your examples. Thank you for sharing!

@Thomas_Mahon I’ve already done that. The issue is getting the correct data structure with [MultiReturn(new[] { "out" })] with just one output port. is it achievable or @erfajo suggestion is the only solution?