Okay - I'm not even sure that the term is right - and I'm sure there is bound to be a term for this - but I'll do my best to explain. This is not quite a cross product here, and the order of the results are absolutely crucial.
Given:
IEnumerable<IEnumerable<string>> sets =
new[] {
/* a */ new[] { "a", "b", "c" },
/* b */ new[] { "1", "2", "3" },
/* c */ new[] { "x", "y", "z" }
};
Where each inner enumerable represents an instruction to produce a set of concatenations as follows (the order here is important):
set a* = new string[] { "abc", "ab", "a" };
set b* = new string[] { "123", "12", "1" };
set c* = new string[] { "xyz", "xy", "x" };
I want to produce set ordered concatenations as follows:
set final = new string { a*[0] + b*[0] + c*[0], /* abc123xyz */
a*[0] + b*[0] + c*[1], /* abc123xy */
a*[0] + b*[0] + c*[2], /* abc123x */
a*[0] + b*[0], /* abc123 */
a*[0] + b*[1] + c*[0], /* abc12xyz */
a*[0] + b*[1] + c*[1], /* abc12xy */
a*[0] + b*[1] + c*[2], /* abc12x */
a*[0] + b*[1], /* abc12 */
a*[0] + b*[2] + c*[0], /* abc1xyz */
a*[0] + b*[2] + c*[1], /* abc1xy */
a*[0] + b*[2] + c*[2], /* abc1x */
a*[0] + b*[2], /* abc1 */
a*[0], /* abc */
a*[1] + b*[0] + c*[0], /* ab123xyz */
/* and so on for a*[1] */
/* ... */
a*[2] + b*[0] + c*[0], /* a123xyz */
/* and so on for a*[2] */
/* ... */
/* now lop off a[*] and start with b + c */
b*[0] + c*[0], /* 123xyz */
/* rest of the combinations of b + c
with b on its own as well */
/* then finally */
c[0],
c[1],
c[2]};
So clearly, there are going to be a lot of combinations!
I can see similarities with Numeric bases (since the order is important as well), and I'm sure there are permutations/combinations lurking in here too.
The question is - how to write an algorithm like this that'll cope with any number of sets of strings? Linq, non-Linq; I'm not fussed.
Why am I doing this?
Indeed, why!?
In Asp.Net MVC - I want to have partial views that can be redefined for a given combination of back-end/front-end culture and language. The most basic of these would be, for a given base view View
, we could have View-en-GB
, View-en
, View-GB
, and View
, in that order of precedence (recognising of course that the language/culture codes could be the same, so some combinations might be the same - a Distinct()
will solve that).
But I also have other views that, in themselves, have other possible combinations before culture is even taken into account (too long to go into - but the fact is, this algo will enable a whole bunch of really cool that I want to offer my developers!).
I want to produce a search list of all the acceptable view names, iterate through the whole lot until the most specific match is found (governed by the order that this algo will produce these concatenations in) then serve up the resolved Partial View.
The result of the search can later be cached to avoid the expense of running the algorithm all the time.
I already have a really basic version of this working that just has one enumerable of strings. But this is a whole different kettle of seafood!
Any help greatly appreciated.