Creating a Dictionary which a Tuple of 2 Strings and a Dictionary of 3 Strings

I’m able to create one which is a Tuple of 2 Strings and a Dictionary of 2 Strings, which is this:

but I don’t know how to do one where it’s a Tuple of 2 Strings and a Dictionary of 3 Strings - as there are only 2 drop down boxes when choosing the dictionary element. This is the closest I’ve got

So, can I convince you to consider abandoning using a Tuple and just making your own custom class for the Key and the Value?
Coded workflows now allow this so we dont need to use Tuples for these complex data collections.

I would prefer to use the original method, if indeed it’s possible. My brain is fried lol

Any reason? Tuples part of dictionaries like this get awfully complex and nasty when you can make your own class easily. Your brain will be less fried if you do it in the ‘better way’ :slight_smile:

Hello!

Could you be a bit more explicit about what you are trying to achieve? Specifically how is the Dictionary that contains the 3 strings supposed to be queried. Which would be the key and which would be the value?

You can’t have a Dictionary with more than 2 generic arguments because the Dictionary is a Key - Value data structure, which has a generic argument for the Key type and a generic argument for the Value type.

If you need to use the 3 strings as the Dictionary key, you could use a Tuple with 3 generic arguments System.Tuple<System.String, System.String, System.String>.
If you need to store the strings as values, you could use an array or a collection.

Thank you for your replies so far and to be more specific for my requirements, I have the following fields within a datatable:

PartID- Key
OrderID - Key
PricePaid - Value
Goods PurchasedID - Value
Qty - Value

The PartID and the OrderID need to be my keys and from here, I wish to associate the 3 value, so I recall these further into the running of the Flow based on the two keys matching.

The reason for needing the 3 values incidentally is because I need to divide the Price Paid by the Qty.

The simplest way, by far, is to create some classes in coded workflows and skip the tuples altogether, the dictionary would become super easy.

That being said, based on you saying you need to simply divide the price paid by quantity per partId and Order ID I don’t see why you want a dictionary?
You can simply loop over the data table no? You mention no grouping etc.

hi @steve1977beyond

What you can do is use a combination of PartID#OrderID as KEY
and PricePaid#GoodsPurchasedID#Qty as Value

you can use any separator which wouldn’t be a part of your Variable values. For eg you can take ## or – or :: in between to separate it.
Later when you are able to find the value using the key combination,
You can use a split operation to find the 3 values.

Thanks

Happy Automation! :smiley:

I thought that too but what occurs in the flow is once everything goes into the data table, I iterate through a For Each. Relevant columns are copied to variables (with the prefix ‘current’) but then once it reaches the end, these variables are overwritten. So lets say if I need to recall a value from 3 lines ago, it won’t exist in a variable.

I’ve never created any custom classes before. Do you have any pointer to get me started?

Yeah, its super easy. Tell ChatGPT the names of the fields you want and ask it to write a simple class in C#.

Make a coded source file in UiPath Studio and put the class in, its now an object you can use.

I have created a .cs with this inside:

namespace OrderDetails_Library
{
public class OrderDetails
{
public string PartID { get; set; }
public string OrderID { get; set; }
public string Price { get; set; }
public string GoodsID { get; set; }
public string Qty { get; set; }
}
}

and compiled it into a .dll file

but now im unsure how to get that into UiPath? ChatGPT says to put the code using OrderDetails_Library in the text editor, but unsure where to put it within there

You missed this part. I didnt say compile it into a .dll nor use Visual Studio, which I assume you have.

apologies, thats me overthinking it:

I have created a .cs file now and here are the contents:

namespace Test_Library2
{
    public class OrderDetails
    {
        public List<PurchaseOrder> ExtractPurchaseOrders(DataTable dtFilteredDataTable)
        {
            List<PurchaseOrder> purchaseOrders = new List<PurchaseOrder>();

            foreach (DataRow row in dtFilteredDataTable.Rows)
            {
                PurchaseOrder purchaseOrder = new PurchaseOrder();
                purchaseOrder.PartID = row["PartID"].ToString();
                purchaseOrder.OrderID = row["OrderID"].ToString();
                purchaseOrder.PricePaid = Convert.ToDouble(row["PricePaid"]);
                purchaseOrder.GoodsPurchasedID = row["GoodsPurchasedID"].ToString();
                purchaseOrder.Qty = Convert.ToInt32(row["Qty"]);

                purchaseOrders.Add(purchaseOrder);
            }

            return purchaseOrders;
        }
    }

    public class PurchaseOrder
    {
        public string PartID { get; set; }
        public string OrderID { get; set; }
        public double PricePaid { get; set; }
        public string GoodsPurchasedID { get; set; }
        public int Qty { get; set; }
    }
}

ChatGPT now talks about me creating .dll files. very confusing.

You and Chat GPT. You’ve overcomplicated it by talking about functions to loop over data tables, which is totally irrelevant to wanting to the instruction of ‘Tell ChatGPT the names of the fields you want and ask it to write a simple class in C#’. Its also going to talk about compiling because it doesn’t understand UiPath and coded source files.

I am going on leave for a week so cannot help further, I think maybe I overestimated how easy it is to understand a class with just two properties on it.

:slight_smile: eally do appreciate your help. I have now modified the .cs file to the following:

public class Purchase
{
    public String PartID { get; set; }
    public String OrderID { get; set; }
    public String PricePaid { get; set; }
    public String GoodsPurchasedID { get; set; }
    public String Qty { get; set; }

    // Constructor
    public Purchase(String partID, String orderID, String pricePaid, String goodsPurchasedID, String qty)
    {
        PartID = partID;
        OrderID = orderID;
        PricePaid = pricePaid;
        GoodsPurchasedID = goodsPurchasedID;
        Qty = qty;
    }

    // Default constructor
    public Purchase() { }

    // Method to display purchase details
    public void DisplayPurchaseDetails()
    {
        Console.WriteLine($"Part ID: {PartID}");
        Console.WriteLine($"Order ID: {OrderID}");
        Console.WriteLine($"Price Paid: {PricePaid}");
        Console.WriteLine($"Goods Purchased ID: {GoodsPurchasedID}");
        Console.WriteLine($"Quantity: {Qty}");
    }
}


If you are still available, it would be fantastic to know how to use then use whats been set up within my main flow :slight_smile:

As a follow up to this, I’ve gone back to my original method and weirdly it works but im unclear as to why. If anyone could advise why the variable declaration isn’t as strict as I was led to believe that would be much appreciated.

So based on doing this:

dictionaryOrders = New Dictionary(Of Tuple(Of String, String), Dictionary(Of String, String))

then a For Each row in dtFiltered

di_hSTariff = row(“SKU”).ToString.Trim()
di_orderID = row(“MarketID”).ToString.Trim().Replace(“#”,“”)
di_pricePaid = row(“SoldPriceLessVAT”).ToString()
di_goodsPurchasedID = row(“GoodsPurchasedID”).ToString()
di_Qty = row(“Qty”).ToString()
di_compositeKey = New Tuple(Of String, String)(di_hSTariff, di_orderID)
di_InnerDictionary = New Dictionary(Of String, String)

then a series of assigns to attach my values to the composite key:
di_InnerDictionary(“SoldPriceLessVAT”) = di_pricePaid
di_InnerDictionary(“GoodsPurchasedID”) = di_goodsPurchasedID
di_InnerDictionary(“Qty”) = di_Qty

then a final assign to link up everything, so the key variables are linked to the value variables:

dictionaryOrders(di_compositeKey) = di_InnerDictionary

My Excel headers are: SKU, MarketID, SoldPriceLessVAT, GoodsPurchasedID, Qty

dictionaryorders is set up as follows: System.Collections.Generic.Dictionary<System.Tuple<System.String,System.String>,System.Collections.Generic.Dictionary<System.String,System.String

di_InnerDictionary is set up as follows: System.Collections.Generic.Dictionary<System.String,System.String>

weirdly, it all works but im unclear as to why:
image

…reason being is that I set up dictionaryorders to be a tuple of 2 strings and a dictionary of 2 strings. In addition, di_InnerDictionary was set up as a dictionary of 2 strings.

So why am I able to add a third string?

What “third string” do you mean?

In the example above on the last line

PART03, 56 (These are the 2 Key Values)
SoldPriceLessVAT=5.2, GoodsPurchasedID=ID008, Qty=3 (These are 3 Strings I believe)

No, it is dictionary with three items.

image
In our structure you hane an “outer” dictionary and “inner” dictionary.
Your “outer” dictionary has KEY “Tuple(Of String, String)” (RED) and VALUE the “inner Dictionary(Of String, String)” (GREEN)

Your “inner” dictionary has KEY string and VALUE string, and there are three entries (YELLOW) in the “inner” dictionary (KEY SoldPriceLessVAT = VALUE 2.5, etc.)

Cheers

thank you - so basically its working which is a relief. I thought that that because I had 3 values, that represented 3 strings? i.e. 3 string values.