Click here to Skip to main content
12,887,625 members (32,338 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


7 bookmarked
Posted 23 Sep 2013

Permutations of Dictionary Items

, 3 Jul 2015 CPOL
Rate this:
Please Sign up or sign in to vote.
Generate every permutation of dictionary items.


In this tip, I will present an easy to use method for iterating over all permutations of a model. Each model parameter is defined as an entry into a Dictionary(of String, Object). Any number of model parameters can be used as input and the output is a Dictionary(of Integer, Object) where the integer key is the permutation number and the object is another dictionary that contains the model parameters for that permutation. This is useful in providing every possible set of inputs into a function.


Other permutation examples will give you every instance of a string or integer array. What if your inputs are more complex? By using a Dictionary(of String, Object) for model inputs, a name for the parameter can be defined and the parameters can be anything from a simple array, true/false values, a class, or a structure.

Using the Code

Examples here are in VB. Download for the C# project for C# code.

Use the code by defining a Dictionary(of String, Object) inputs:

Dim d As New Dictionary(Of String, Object)

Dim b() As Boolean = {True, False}
d.Add("IsMarried", b)
d.Add("IsEmployed", b)

d.Add("YearsAtAddress", {2, 5, 10})
d.Add("IncomeLevel", {25000, 50000, 75000, 100000})

Dim cb As New List(Of Credit)
cb.Add(New Credit With {.Bureau = "Equifax", .ScoreAvg = 500})
cb.Add(New Credit With {.Bureau = "Equifax", .ScoreAvg = 600})
cb.Add(New Credit With {.Bureau = "Equifax", .ScoreAvg = 700})
cb.Add(New Credit With {.Bureau = "Transunion", .ScoreAvg = 500})
cb.Add(New Credit With {.Bureau = "Transunion", .ScoreAvg = 600})
cb.Add(New Credit With {.Bureau = "Transunion", .ScoreAvg = 700})
d.Add("Credit", cb) 

Then call the function:

Dim ps As Dictionary(Of Integer, Object) = PermutateDictionary.Permutations(d) 

The result is a dictionary containing all the permutations and the parameters for each.

1: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 25000(IncomeLevel) Equifax-500(Credit)
2: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 25000(IncomeLevel) Equifax-600(Credit)
3: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 25000(IncomeLevel) Equifax-700(Credit)
4: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 25000(IncomeLevel) Transunion-500(Credit)
5: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 25000(IncomeLevel) Transunion-600(Credit)
6: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 25000(IncomeLevel) Transunion-700(Credit)
7: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 50000(IncomeLevel) Equifax-500(Credit)
8: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 50000(IncomeLevel) Equifax-600(Credit)
9: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 50000(IncomeLevel) Equifax-700(Credit)
10: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 50000(IncomeLevel) Transunion-500(Credit)
11: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 50000(IncomeLevel) Transunion-600(Credit)
12: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 50000(IncomeLevel) Transunion-700(Credit)
13: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 75000(IncomeLevel) Equifax-500(Credit)
14: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 75000(IncomeLevel) Equifax-600(Credit)
15: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 75000(IncomeLevel) Equifax-700(Credit)
16: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 75000(IncomeLevel) Transunion-500(Credit)
17: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 75000(IncomeLevel) Transunion-600(Credit)
18: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 75000(IncomeLevel) Transunion-700(Credit)
19: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 100000(IncomeLevel) Equifax-500(Credit)
20: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 100000(IncomeLevel) Equifax-600(Credit)
21: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 100000(IncomeLevel) Equifax-700(Credit)
22: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 100000(IncomeLevel) Transunion-500(Credit)
23: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 100000(IncomeLevel) Transunion-600(Credit)
24: True(IsMarried) True(IsEmployed) 2(YearsAtAddress) 100000(IncomeLevel) Transunion-700(Credit)
281: False(IsMarried) False(IsEmployed) 10(YearsAtAddress) 75000(IncomeLevel) Transunion-600(Credit)
282: False(IsMarried) False(IsEmployed) 10(YearsAtAddress) 75000(IncomeLevel) Transunion-700(Credit)
283: False(IsMarried) False(IsEmployed) 10(YearsAtAddress) 100000(IncomeLevel) Equifax-500(Credit)
284: False(IsMarried) False(IsEmployed) 10(YearsAtAddress) 100000(IncomeLevel) Equifax-600(Credit)
285: False(IsMarried) False(IsEmployed) 10(YearsAtAddress) 100000(IncomeLevel) Equifax-700(Credit)
286: False(IsMarried) False(IsEmployed) 10(YearsAtAddress) 100000(IncomeLevel) Transunion-500(Credit)
287: False(IsMarried) False(IsEmployed) 10(YearsAtAddress) 100000(IncomeLevel) Transunion-600(Credit)
288: False(IsMarried) False(IsEmployed) 10(YearsAtAddress) 100000(IncomeLevel) Transunion-700(Credit) 

The code to produce the output is:

For Each p In ps
    Console.Write(CStr(p.Key) + ": ")
    For Each e In p.Value
        If TypeName(e.value) = "Credit" Then
            Console.Write(CStr(e.value.Bureau + "-" + _
                          e.value.ScoreAvg.ToString) + "(" + e.key + ") ")
            Console.Write(CStr(e.value) + "(" + e.key + ") ")
        End If

The code that does the work is:

Public Class PermutateDictionary

    Shared Function Permutations(ds As Dictionary(Of String, Object)) _
        As Dictionary(Of Integer, Object)

        Dim pCount As Integer = 1
        Dim sPointer As New Dictionary(Of String, Integer)
        Dim pNumber As Integer
        Dim result As New Dictionary(Of Integer, Object)

        For Each d In ds

            pCount *= GetEntryCount(d)
            sPointer.Add(d.Key, 0)

        For pNumber = 1 To pCount

            Dim pEntry As New Dictionary(Of String, Object)
            For Each d In ds
                pEntry.Add(d.Key, d.Value(sPointer(d.Key)))
            result.Add(pNumber, pEntry)

            'Iterate and increment the pointers
            For Each d In ds.Reverse
                sPointer(d.Key) += 1
                If sPointer(d.Key) = GetEntryCount(d) Then
                    sPointer(d.Key) = 0
                    Exit For
                End If
        Return result

    End Function

    Private Shared Function GetEntryCount(ByRef Entry As Object) _
        As Integer

            Return Entry.Value.length
        Catch ex As Exception
            Return Entry.Value.count
        End Try
    End Function
End Class 

Download the sample project. I hope you find this useful.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

United States United States
Software developer since 1981. Currently specializing in VB and .NET.

You may also be interested in...

Comments and Discussions

QuestionRe: Files Pin
Kalkidas26-Sep-13 9:57
memberKalkidas26-Sep-13 9:57 
AnswerRe: Files Pin
RoarkDude26-Sep-13 10:32
memberRoarkDude26-Sep-13 10:32 

There's a "Browse Code" link left-top of the article.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170424.1 | Last Updated 3 Jul 2015
Article Copyright 2013 by RoarkDude
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid