2012-03-14 86 views
0

我有一個小問題:)我有一個列表,其中一些參數是重複的。我必須刪除它。我不能使用Distinct becouse我只能看到在一些領域(不是全部)。我認爲這是使用lambda epxressions的好選擇。動態在哪裏條件

我對我的對象有一個聲明,我工作的人不一樣,但想法是相似的。

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"}}); 
} 

的鍵列始終具有相同的lenght爲repeatedValues - 而改變,一些lenghts是1,其他2,3,5。不超過5個

這些鍵就像數據庫表上的primaryKeys。它非常相似。所以我們在「主鍵列」中尋找重複內容 - 我認爲這是一個很好的比較。

我們在該示例中看到,「column1」中的值爲5,「column2」中的值爲15。我以前說我必須刪除那個,但在我必須重複項目之前。

我嘗試做這樣的代碼(我知道FUNC方法awalys失敗becouse(對象)1 ==(對象)1總是返回假,但它的例子:

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給我一個例外 變量'x'的類型'System.Collections.Generic.Dictionary`2'System.String,System.Object]'from scope'',但它沒有被定義

可以這樣做?

(不是例外)在其他步驟也許該表達式要求例如重複值[i](之後),它將不知道它是什麼?

回答

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); 

編輯:改變例如使得其每次放散列在同一列的順序。

+0

這是一個選項,但我嘗試使用HashSet和StringBuilder - 它工作得更快,但是如果我使用表達式樹,它的工作速度會加快一半 - 我不喜歡,但它是真的 – user1091406 2012-03-14 21:21:24

+0

是的,這是概念驗證和進一步優化的起點。 – 2012-03-14 21:40:55