4
A
回答
-1
我有一個IDEEA:使用表達式樹動態生成的代碼已經做了你需要的東西:
這裏是一個完整的解決方案:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
namespace testProjectExpressions
{
class Program
{
static void Main(string[] args)
{
List<int> lst1 = new List<int>()
{
1,
2,
3
};
List<int> lst2 = new List<int>()
{
4,
5,
6
};
List<int> lst3 = new List<int>()
{
7,
8
};
var fnc = CartesianProduct<int>(3);
var res = fnc(new[] {lst1, lst2, lst3 });
foreach (var product in res)
{
for (int index = 0; index < product.Length; index++)
{
var productVar = product[index];
if (index < product.Length - 1)
Console.Write(productVar + ",");
else
{
Console.WriteLine(productVar);
}
}
}
Console.ReadKey();
}
private static Func<List<T>[], List<T[]>> CartesianProduct<T>(int howMany)
{
var inputArrayOfLists = Expression.Parameter(typeof (List<T>[]), "inputArgument");
ParameterExpression[] loopVariables = new ParameterExpression[howMany];
for (int index = 0; index < howMany; index++)
if (loopVariables[index] == null)
loopVariables[index] = Expression.Variable(typeof (T));
List<Expression> finalStatements = new List<Expression>();
// emit the create new object
var resultExpression = Expression.Variable(typeof (List<T[]>), "result");
var assignExpression = Expression.Assign(resultExpression, Expression.New(typeof (List<T[]>)));
finalStatements.Add(assignExpression);
// the "Add" method
MethodInfo addMethod = typeof (List<T[]>).GetMethod("Add", BindingFlags.Instance | BindingFlags.Public);
var EnumerableType = typeof(IEnumerable<T>);
MethodInfo GetEnumeratorMethod = EnumerableType.GetMethod("GetEnumerator");
var moveNextMethod = typeof(IEnumerator).GetMethod("MoveNext");
Expression recursiveExpression = null;
for (int index = 0; index < howMany; index++)
{
var variable = loopVariables[index];
var indexAccess = Expression.ArrayIndex(inputArrayOfLists, Expression.Constant(index));
var currentListExpression = indexAccess;
if (recursiveExpression == null)
{
var arrayVariable = Expression.Variable(typeof (T[]), "myArray");
List<Expression> initExpressions = new List<Expression>();
List<Expression> statements = new List<Expression>();
var assign = Expression.Assign(arrayVariable, Expression.NewArrayInit(typeof (T), loopVariables));
statements.Add(assign);
Expression callAddExpression = Expression.Call(resultExpression, addMethod, arrayVariable);
statements.Add(callAddExpression);
recursiveExpression = Expression.Block(new[] {arrayVariable}, statements);
}
recursiveExpression = ForEachExpression(typeof(IEnumerator<T>), GetEnumeratorMethod, moveNextMethod,
currentListExpression, variable, recursiveExpression);
}
finalStatements.Add(recursiveExpression);
finalStatements.Add(resultExpression);
List<ParameterExpression> blockParameters = new List<ParameterExpression>(loopVariables);
blockParameters.Add(resultExpression);
Expression block = Expression.Block(blockParameters, finalStatements);
var compiled = Expression.Lambda(block, inputArrayOfLists).Compile() as Func<List<T>[], List<T[]>>;
return compiled;
}
// compiles a foreach expression on the given collection!
public static Expression ForEachExpression(
Type enumeratorType,
MethodInfo getEnumeratorMethod,
MethodInfo moveNextMethod,
Expression collection,
ParameterExpression loopVariable,
Expression loopContent)
{
var breakLabel = Expression.Label("STOP");
var enumeratorVar = Expression.Variable(enumeratorType, "collectionEnumerator");
var loop = Expression.Block(new[] { enumeratorVar },
Expression.Assign(enumeratorVar, Expression.Call(collection, getEnumeratorMethod)), // var enumerator = collection.GetEnumerator();
Expression.Loop(
Expression.IfThenElse(
Expression.Equal(Expression.Call(enumeratorVar, moveNextMethod), Expression.Constant(true)), // daca move_next e true
Expression.Block(new[] { loopVariable },
Expression.Assign(loopVariable, Expression.Property(enumeratorVar, "Current")), // loopVariable = enumeratorVar.Current
loopContent // do some stuff with that entity
),
Expression.Break(breakLabel) // jmp to break
),
breakLabel) // break
);
return loop;
}
}
}
相關問題
- 1. Python的笛卡爾乘積
- 2. 反向笛卡爾乘積
- 3. 笛卡爾乘積加入
- 4. 笛卡爾乘積在SSIS
- 5. 多個陣列的笛卡爾乘積
- 6. 用F#計算笛卡爾乘積列表的乘積
- 7. Sql Server的意外笛卡爾乘積
- 8. 笛卡爾乘積的Matlab向量化
- 9. javascript中對象的笛卡爾乘積
- 10. 不同尺寸的笛卡爾乘積
- 11. MATLAB中的笛卡爾乘積
- 12. SQL:避免笛卡爾乘積的usauge
- 13. 笛卡爾積
- 14. 笛卡爾乘積爲小組成員
- 15. 生成n套笛卡爾乘積
- 16. 笛卡爾乘積數據幀
- 17. n-ary笛卡爾乘積inRxJava
- 18. 計算n元笛卡爾乘積
- 19. 多態查詢和笛卡爾乘積
- 20. 迭代笛卡爾乘積很慢
- 21. 避免笛卡爾乘積檢查對
- 22. 笛卡爾積Ruby
- 23. 笛卡爾積SQL
- 24. AWK笛卡爾積
- 25. 笛卡爾積 - PHP
- 26. 笛卡爾積VBA
- 27. RxJs笛卡爾積
- 28. 笛卡爾的力量(笛卡爾乘積與自我任意時間)
- 29. OCaml中的列表的笛卡爾(外部)乘積
- 30. 2D矢量(笛卡爾乘積)中元素的所有排列
參見:http://blogs.msdn.com/ b/ericlippert /存檔/ 2010/06/28 /計算-A-笛卡兒積與 - linq.aspx –
參考文獻:http://stackoverflow.com/questions/3093622/generating-all-possible-combinations –
@AnthonyPegram我會把這個評論作爲答案,因爲它是完整的,並將幫助其他人在未來搜索類似問題的解決方案 –