-1

I am trying to generate a table which would show all possible combinations based on the key. To make it more clear lets say I have a kind of Key, Value pair set(Its mentioned kind of because there are unique keys and different values). I need to fill the table with all possible combinations of the values with different keys.

Sample input and output

Now i need to make the key as the heading of the table and add the values accordingly so that there are no duplicate rows and all combinations are present. I am doing it in C#. I could only retrieve these key value pairs from my database based on conditions, but I have no idea how the table can be built.

Are there any examples someone could provide? Or a basic approach I should follow to achieve it?

So far my ideas:

To create an array with size equals number of distinct parameters of key. Add values to the array and then pass a list of the Array to the View.

P.S : My data model is complex. Reference to this question would give an idea of a part of my Data model. The value I am talking about comes from the SetValue described in the model and the key from another class which is not described (I feel this information is irrelevant as I have already the list of my Key value pairs). I think I have posted the question in the right forum, as I am not asking for any code. If not please let me know the right forum where this question will belong to.

2 Answers 2

1

If you have a fixed number of types like you do in this case (color, fruit, vegetable), then you can do it easily with nested loops. For example:

foreach (var color in colors)
{
    foreach (var fruit in fruits)
    {
        foreach (var veg in vegetables)
        {
            rows.Add(new Row(color, fruit, vegetable));
        }
    }
}

That gets unwieldy if your number of different things grows, though.

You can, however, generalize that to a class that will generate permutations for any number of different things.

1
  • I am not having fixed number of types. But I could figure out a way to do it. By recursively calculating the Cartesian Product. [here][stackoverflow.com/a/33756164/5243291] you can find the link to the answer i did to solve the task.
    – Vini
    Nov 20, 2015 at 12:59
1

I have managed to do a more versatile version, that allows multiple properties with list of values to be permuted. It is rather silly (does not use LINQ, as input data is a OrderedDictionary) and can be improved if input data is in a more friendly format.

// hold index data for permutations
class IndexData
{
    public int PropIndex { get; set; }
    public int MaxCount { get; set; }
}

// input data - OrderedDictionary helps with the key order, but has serious non-typed drawbacks
var propsValues = new OrderedDictionary()
{
    { "colour", new List<String>() { "red", "blue", "violet", "black", "yellow"}},
    { "fruit", new List<String>() { "apple", "mango", "banana", "banana"}},
    { "vegetable", new List<String>() { "onion", "potato", "tomato"}},
    { "shape", new List<String>() { "round", "oval" }}
};

// compute index containers to help with permutations
var propsIndexes = new Dictionary<String, IndexData>();
var propsKeys = new List<String>();
foreach (var key in propsValues.Keys)
{
    propsKeys.Add((String) key);
    propsIndexes.Add((String) key, new IndexData() { PropIndex = 0, MaxCount = (propsValues[key] as List<String>).Count});
}

int propCount = propsValues.Count;
String lastKey = propsKeys[propCount - 1];

// count the permutations until the "most significant" property (the one changing least often) has reached its count
for (int combinationIndex = 0; ; combinationIndex ++ )
{
    var sb = new StringBuilder();
    sb.AppendFormat("{0}: ", combinationIndex + 1);
    foreach (var key in propsValues.Keys)
    {
        int propIndex = propsIndexes[(String)key].PropIndex;
        sb.AppendFormat("{0} ", ((propsValues[(String)key] as List<String>)[propIndex]));
    }
    Console.WriteLine(sb.ToString());

    // incrementing indexes
    bool exit = false;
    propsIndexes[lastKey].PropIndex++;

    for (int i = propCount - 1; i >= 0; i--)
    {
        String propKey = (String)propsKeys[i];

        // current index has reached its count - incrementing previous one and resetting current one
        if (propsIndexes[propKey].PropIndex >= propsIndexes[propKey].MaxCount)
        {
            propsIndexes[propKey].PropIndex = 0;

            // "most significant" property has reached its count
            if (i == 0)
            {
                exit = true;
                break;
            }

            String prevPropKey = (String)propsKeys[i - 1];
            propsIndexes[prevPropKey].PropIndex++;
        }
    }

    if (exit)
        break;
}
1
  • I will check if the solution works for me ASAP. Thanks for your answer.
    – Vini
    Dec 20, 2015 at 18:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.