我有两个列表,每个列表中有多个数据。并且需要低于输出,这将是list(s)的组合值。
Example1:
List1: {"A","B","C"}
List2: {"D","E"}
Expected Output Combinations:
{"A"}
{"B"}
{"C"}
{"D"}
{"E"}
{"A,D"}
{"A,E"}
{"B,D"}
{"B,E"}
{"C,D"}
{"C,E"}
Example2:
List1: {"A","B"}
List2: {"D"}
Expected Output Combinations:
{"A"}
{"B"}
{"D"}
{"A,D"}
{"B,D"}
以下是我正在尝试的代码段:
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> source, int n)
{
if (n == 0) yield return Enumerable.Empty<T>();
int count = 1;
foreach (T item in source)
{
foreach (var innerSequence in source.Skip(count).Combinations(n - 1))
{
yield return new T[] { item }.Concat(innerSequence);}count++;
}
}
}
public static IEnumerable<IEnumerable<T>> AllCombinations<T>(this IList<T> source)
{
IEnumerable<IEnumerable<T>> output = Enumerable.Empty<IEnumerable<T>>();
for (int i = 0; i < source.Count; i++)
{
output = output.Concat(source.Combinations(i));
}
return output;
}
...
List<string> lstCodes = new List<string>();
List<string> lstCodeOut = new List<string>();
if (!String.IsNullOrEmpty(txtbox1.Text))
lstCodes.AddRange(txtbox1.Text.Split(',').ToList());
if (!String.IsNullOrEmpty(txtbox2.Text))
lstCodes.AddRange(txtbox2.Text.Split(',').ToList());
if (!String.IsNullOrEmpty(txtbox3.Text))
lstCodes.AddRange(txtbox3.Text.Split(',').ToList());
foreach (var sequence in lstCodes.AllCombinations())
{
lstCodeOut.Add(string.Join(",", sequence));
}
txtBox.Text = string.Join(Environment.NewLine, lstCodeOut);
答案 0 :(得分:0)
最直接的方法是使用基本的foreach循环;假设没有重复:
var l1 = new List<string> { "A", "B", "C" };
var l2 = new List<string> { "D", "E" };
var result = new HashSet<string>();
foreach( string s1 in l1 )
{
result.Add( s1 );
foreach( string s2 in l2 )
{
result.Add( s2 );
result.Add( $"{s1},{s2}" );
}
}
从这里开始,我们可以通过连接2个列表然后将2合并到组合中来重构以消除内部循环中的一些冗余:
var l1 = new List<string> { "A", "B", "C" };
var l2 = new List<string> { "D", "E" };
var result = new List<string>( l1.Concat( l2 ) );
foreach( string s1 in l1 )
{
foreach( string s2 in l2 )
{
result.Add( $"{s1},{s2}" );
}
}
从这里开始,我们可以再次重构为LINQ语句:
var l1 = new List<string> { "A", "B", "C" };
var l2 = new List<string> { "D", "E" };
string[] result = l1
.Concat( l2 )
.Concat( l1.SelectMany( s1 => l2, ( s1, s2 ) => $"{s1},{s2}" ) )
.ToArray();