2012-03-14 13 views
0

私は少し問題があります:)私はいくつかの引数が重複しているリストを持っています。私はそれを削除する必要があります。私はいくつかのフィールド(すべてではない)で見る必要があるので、Distinctを使用することはできません。ラムダのエクスプレッションを使用するのは素晴らしいオプションだと思います。動的条件

私は自分のオブジェクトについて宣言していますが、同じではありませんが、アイデアは似ています。

var keys = new string[] {"column1", "column2"}; 
var repeatedValues = new object[] {5, 15}; 

var values = new List<Dictionary<string, object>>(); 

//MAKE FAKE DOUBLE 
values.Add(new Dictionary<string, object> { 
      { "column1", 5 }, { "column2", 15 }, { "column3", "test" }, 
      { "column4", "test1" } }); 

for (int i = 0; i < 10; i++) 
{ 
    values.Add(new Dictionary<string, object> { 
       {"column1", i}, {"column2", 10 + i}, "column3", "test"}, 
       {"column4", "test1"}}); 
} 

キー列は常にrepeatedValuesと同じな長さを持っている - が、変更され、いくつかのlenghtsは1、他の2,3,5です。 5を超えない

キーはデータベーステーブルのprimaryKeysに似ています。それはかなり似ています。だから私たちは "主キーの列"で重複を探して - 私は良いと思う比較する。

この例では、重複が "column1"に値5、 "column2"に値15を持つことがわかります。私は前にどのように私はそれを削除する必要がありますが、私は繰り返し項目を数える必要があります前に言う。

私は(私はFUNCメソッドawalysは(オブジェクトbecouse失敗知っているようなコードを実行してみてください)1 ==(オブジェクト)1は、常にfalseを返しますが、それは例です:

Expression expression = null; 

for (int i = 0; i < keys.Length; i++) 
{ 
    Expression<Func<Dictionary<string, object>, bool>> exp = x => x[keys[i]] == repeatedValues[i]; 

    if (expression == null) 
     expression = exp.Body; 
    else 
     expression = Expression.AndAlso(expression, exp.Body); 
} 

var parameterExpression = Expression.Parameter(typeof (Dictionary<string, object>), "x"); 

var lamba = Expression.Lambda<Func<Dictionary<string, object>, bool>>(expression, parameterExpression); 

var res = lamba.Compile(); 
var counts = queryLis.Count(res); 

しかしcompilatorは私に例外を与えます 'System.Collections.Generic.Dictionary`2 [System.String、System.Object]'の変数 'x'がスコープ ''から参照されていますが、定義されていません。

この方法でこれを行うことができます?

(例外ではありません)他のステップでおそらく式は例えばrepeatedValues [i](forの後)を要求し、それが何であるか分からないでしょうか?

答えて

0

元の式が参照しているものと同じExpression.Parameterを渡す必要があります。
同じ名前の新しいExpression.Parameterを作成するのは十分ではありません。

0

なぜExpressionなどを使いこなしているのか分かりません。私があなたを正しく理解していれば、値の各エントリが列がフィールド名を表すデータの行であるという関係データベースの状況を本質的に複製しています。そのような場合は、データベースブックからページを取得し、インデックスから作業することもできます。それは、同じ列の順序にするたびにハッシュを置くように変更された例:

// testing for duplicates 
List<Dictionary<string, object>> duplicates = new List<Dictionary<string, object>>(); 
List<string> index = new List<string>(); 
foreach (var value in values) 
{ 
    List<string> keyValues = new List<string>(); 
    foreach (string key in keys) 
    { 
     keyValues.Add(value[key].GetHashCode().ToString()); 
    } 
    string hash = string.Join(",", keyValues.ToArray()); 
    if (index.Contains(hash)) 
     duplicates.Add(value); 
    else 
     index.Add(hash); 
} 

var cleanList = values.Except(duplicates); 

EDIT:あなたの最初のスニペットの後、あなたはそうのようなクリーンアップリストで取得することができます。

+0

これはオプションですが、HashSetとStringBuilderを試してみましょう。より速く動作しますが、式のツリーを使用すると半分の速さで動作しますが、私は負けませんが、それは真実です – user1091406

+0

これは概念の証明ですさらなる最適化の出発点。 –