将列表字典转换为字典列表

时间:2012-12-29 08:29:59

标签: c#

我有一个Dictionary<string, List<string>>类型的字典,我想将其转换为List<Dictionary<string, string>>类型的列表。例如,

输入:

  Key              List
{ id,   { "1",     "2",    "3"   }},
{ mkt,  { "in",    "uk",   "us"  }},
{ dept, { "sales", "test", "var" }},

输出:

{ 
  { (id, "1"), (mkt , "in"), (dept, "sales") },  //1st Node as Dictionary
  { (id, "1"), (mkt , "in"), (dept, "test")  },  //2nd Node
  { (id, "1"), (mkt , "in"), (dept, "var")   },
  .
  . //All possible combinations id, mkt and dept
  .
 }

我能够使用for循环,但我正在寻找一种更干净的方式,可能使用一些C#特定功能,如LINQ等。

int a = 0;
int NoOfTimesToRepeatAnElement = 1, NoOfTimesToRepeatList = count;
int prevListSize = 1, currListSize = 1;
foreach (var arg in dictionary)
{
    a = 0;
    prevListSize = currListSize;
    currListSize = arg.Value.Count();

    NoOfTimesToRepeatAnElement = NoOfTimesToRepeatAnElement * prevListSize;
    NoOfTimesToRepeatList = NoOfTimesToRepeatList / currListSize;

    var list = arg.Value;

    for (int x = 0; x < NoOfTimesToRepeatList; x++)
    {
        for (int y = 0; y < currListSize; y++)
        {
            for (int z = 0; z < NoOfTimesToRepeatAnElement; z++)
            {
                finalList[a++].Add(arg.Key, list[y]);
            }
        }
    }
}

PS:我来自C背景,是C#的新手

1 个答案:

答案 0 :(得分:0)

var list = dict.Select(kv => kv.Value.Select(v => new { kv.Key, Value = v }))
                .CartesianProduct()
                .Select(x => x.ToDictionary(y=>y.Key,y=>y.Value))
                .ToList();

public static partial class MyExtensions
{
    //http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx
    public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
    {
        // base case: 
        IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() };
        foreach (var sequence in sequences)
        {
            var s = sequence; // don't close over the loop variable 
            // recursive case: use SelectMany to build the new product out of the old one 
            result =
                from seq in result
                from item in s
                select seq.Concat(new[] { item });
        }
        return result;
    }
}