0

from this dictionary

var foo = new Dictionary<string, IEnumerable<object>>
        {
            {"key1", new object[] {1}}, 
            {"key2", new[] {"one", "two"}}, 
            {"key3", new[] {"three", "four"}}
        }

i'd like to get this IEnumerable<dictionary<string, object>>

IEnumerable<Dictionary<string, object>> bar = {
     {{"key1", 1}, {"key2", "one"}, {"key3", "three"}},
     {{"key1", 1}, {"key2", "one"}, {"key3", "four"}},
     {{"key1", 1}, {"key2", "two"}, {"key3", "three"}},
     {{"key1", 1}, {"key2", "two"}, {"key3", "four"}}
} 

To speak simply, I need C#'s analog of python itertools.product function Cartesian product of a dictionary of lists.

I've read Generating all Possible Combinations but couldn't figure out how i should change it and i couldn't found solution about cartesian product with dictionaries (with keys) result.

Thanks in advance

vvkirik1
  • 3
  • 1
  • I tried following public static IEnumerable> CartesianProductT( Dictionary> sequences) { IEnumerable> emptyProduct = new[] {new Dictionary()}; return sequences.Aggregate(emptyProduct, (accumulator, sequence) => accumulator.SelectMany(_ => sequence.Value, (acc, item) =>{ acc.TryAdd(sequence.Key, item); return acc; })); } but it returns 4 duplicates of first row of needed result – vvkirik1 Feb 22 '22 at 15:43
  • @vvkirik1, please note that the return type cannot be `IEnumerable>`, maybe it should be `IEnumerable>>` – user449689 Feb 22 '22 at 16:37

1 Answers1

0

Quick solution would be to do only cartesian product of dictionary values while preserving information about keys, and next recreate dictionaries:

           // [[("key1",1)],[("key2","one"),("key2,"two")],[("key3","three"),("key3","four")]]
            var collectionsOfKeyValuePairs =
                foo.Select(k => k.Value.Select(v => new KeyValuePair<string, object>(k.Key, v)));
            // [[(key1,1),(key2,one),(key3,three)],
            //  [(key1,1),(key2,one),(key3,four)],...etc
            var product = CartesianProduct(collectionsOfKeyValuePairs);
            
            var dictionaries = product.Select(collection=> collection.ToDictionary(k=> k.Key, k=> k.Value));
lukbl
  • 1,763
  • 1
  • 9
  • 13