2015-05-06 41 views
2

我有一個包含多個列的列表。我想根據請求的列名稱(列名稱將作爲參數)篩選具有不同值的列表。從列表中獲取請求的列不同值

IList<obj1> objTemp= new List<obj1>(); 
for (int i = 0; i < 15; i++) 
{ 
    obj1 temp= new obj1(); 
    temp.Name = "Name" + i; 
    temp.Age= "Age" + i; 
    temp.Company= "Company" + i; 
    objTemp.Add(temp); 
} 

var distinctTypeIDs = objTemp.Select(x => x.**{my requested column}**).Distinct(); 
+0

您可以使用switch語句來檢查基於該列的列名稱和排序列表。 – Mairaj

+0

歡迎來到Stack Overflow!與論壇網站不同,我們不使用「謝謝」或「任何幫助表示讚賞」,或在[so]上簽名。請參閱「[應該'嗨','謝謝',標語和致敬從帖子中刪除?](http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be - 刪除 - 從帖子)。順便說一句,這是「預先感謝」,而不是「感謝先進」。 –

回答

1

您可以使用反射由它的名字獲得所需屬性:

var distinctTypeIDs = objTemp.Select(x => x.GetType().GetProperty("requested_column").GetValue(x)) 
          .Distinct(); 
+0

感謝您的重播,它是爲我工作,但返回作爲對象列表類型...我們可以得到相同的與相同的對象(我用來做過濾器 - objTemp) – Mahendhar

+0

@Mahendhar Select將始終返回已使用內部表達式的對象的列表,它始終是您的案例中的一個屬性。能否請您提供輸入和輸出correclty? –

1

一種方法是使用這樣的方法。

private IList<obj1> SortListAccordingToParameter(string filter) 
{ 
if(filter == "Name") 
    return objTemp.Select(x => x.Name).Distinct(); 
else if(filter == "Age") 
    return objTemp.Select(x => x.Age).Distinct(); 
else if(filter == "Company") 
    return objTemp.Select(x => x.Company).Distinct(); 
} 
+0

我認爲這意味着x.Name,x.Age和x.Company在那裏。 – AlwaysLearning

+0

是的。使用反射的解決方案雖然更好。 – Mattias

+0

取決於您的「更好」的定義 - 確定我的表達解決方案或反射/匿名類型的實現情況很好,但你的執行速度可能最快,而且最清晰。如果我知道類型定義永遠不會改變,我可能會用類似的東西去做。 – jdphenix

1

如果您知道要搜索的屬性的類型,則可以使用表達式。

string propName = "Age"; 
var paramExpression = Expression.Parameter(typeof(Obj1)); 
// o => 

var memberExpression = Expression.Property(paramExpression, propName); 
// o => o.Age 

var lambdaExpression = Expression.Lambda<Func<Obj1, string>>(memberExpression, paramExpression); 
// (o => o.Age) 

var compiled = lambdaExpression.Compile(); 

IList<Obj1> objTemp = new List<Obj1>(); 
for (var i = 0; i < 15; i++) { 
    Obj1 temp = new Obj1(); 
    temp.Name = "Name" + i; 
    temp.Age = "Age" + i; 
    temp.Company = "Company" + i; 
    objTemp.Add(temp); 
} 

var results = objTemp.Select(compiled); 
// equivalent to objTemp.Select(o => o.Age), plus a delegate call and the time to 
// compile the lambda. 

我可能會在一個靜態類包裝這件事,像這樣:

static class Gen<TModel, TProp> { 
    public static Func<TModel, TProp> SelectorExpr(string propertyName) { 
     var pExpr = Expression.Parameter(typeof (TModel)); 
     var mExpr = Expression.Property(pExpr, propertyName); 
     var lExpr = Expression.Lambda<Func<TModel, TProp>>(mExpr, pExpr); 
     return lExpr.Compile(); 
    } 
} 

這樣你可以寫你的選擇,如:

var results = objTemp.Select(Gen<Obj1, string>.SelectorExpr(propName)); 

這似乎更加清晰一點對我來說,我正在做什麼,特別是如果我正在閱讀表達DOM代碼,我寫了6個月後。

1

我一直是「映射」列的風扇負責檢索該列的內容的匿名方法:

using System; 
using System.Collections.Generic; 
using System.Linq; 

public class Program 
{ 
    public static void Main() 
    { 
     Console.WriteLine("Hello World"); 
     var items = new List<SomeObject> {new SomeObject { Age = 10, Name = "Daniel", Company = "InCycle" }, 
             {new SomeObject { Age = 20, Name = "Not Daniel", Company = "Not InCycle" } 
             }}; 

     var result = Filter<int>(items, "Age"); 
     Console.WriteLine(result.Last()); 

    } 

    public static IEnumerable<T> Filter<T>(IEnumerable<SomeObject> items, string filterCriteria) 
    { 
     var mappings = new Dictionary<string, Func<IEnumerable<SomeObject>, IEnumerable<T>>> 
     { 
      { "Age", filterItems => filterItems.Select(item => item.Age).Distinct().Cast<T>() }, 
      { "Name", filterItems => filterItems.Select(item => item.Name).Distinct().Cast<T>() }, 
      { "Company", filterItems => filterItems.Select(item => item.Company).Distinct().Cast<T>() } 
     }; 

     return mappings[filterCriteria](items); 

    } 
} 

public class SomeObject 
{ 
    public int Age {get;set;} 
    public string Name {get;set;} 
    public string Company {get; set;} 
} 

對這個缺點的做法是,如果添加額外的屬性,你可以忘記將它們添加到過濾。表達式也是一種可靠的方法。

0
public class Test 
{ 
    public string name { get; set; } 
    public string age { get; set; } 
    public string contact { get; set; } 

    public Test getName(string name) 
    { 
     List<Test> testList = new List<Test>(); 

     testList.Add(new Test { name = "Developer", age = "24", contact = "99009900990" }); 
     testList.Add(new Test { name = "Tester", age = "30", contact = "009900990099" }); 

     return testList.Where(c => c.name == name).FirstOrDefault(); 
    } 
    } 
    static void Main(string[] args) 
    { 
     Test testObj = new Test(); 
     Test selectedObj = testObj.getName("Developer"); 
    }