从列表中获取请求的列不同值

时间:2021-11-20 13:09:00

I have a list with multiple columns. I want to filter the list based on the requested column name (column name will come as a parameter) with distinct values.

我有一个包含多列的列表。我想根据请求的列名称(列名将作为参数)过滤列表,并使用不同的值。

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

5 个解决方案

#1


You can use reflection for getting desired property by it's name:

您可以使用反射来获取所需属性的名称:

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

#2


I've always been a fan of "mapping" a column to an anonymous method responsible for retrieving the contents of that column:

我一直喜欢将列“映射”到负责检索该列内容的匿名方法:

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

The downside to this approach is that if you add additional properties, you could forget to add them to the filtering. Expressions are a solid approach as well.

这种方法的缺点是,如果添加其他属性,您可能会忘记将它们添加到过滤中。表达式也是一种可靠的方法。

#3


One way is to use a method like this.

一种方法是使用这样的方法。

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

#4


If you know the type of the property you will be searching for, you could use expressions.

如果您知道要搜索的属性的类型,则可以使用表达式。

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. 

I would probably wrap this up in a static class, like this:

我可能会将它包装在一个静态类中,如下所示:

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

that way you can write your selector like:

这样你就可以编写你的选择器:

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

That seems a bit more clear to me what it is I'm doing, especially if I'm reading expression DOM code I wrote 6 months after.

这对我来说似乎更清楚我正在做什么,特别是如果我正在阅读我在6个月后写的表达DOM代码。

#5


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

#1


You can use reflection for getting desired property by it's name:

您可以使用反射来获取所需属性的名称:

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

#2


I've always been a fan of "mapping" a column to an anonymous method responsible for retrieving the contents of that column:

我一直喜欢将列“映射”到负责检索该列内容的匿名方法:

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

The downside to this approach is that if you add additional properties, you could forget to add them to the filtering. Expressions are a solid approach as well.

这种方法的缺点是,如果添加其他属性,您可能会忘记将它们添加到过滤中。表达式也是一种可靠的方法。

#3


One way is to use a method like this.

一种方法是使用这样的方法。

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

#4


If you know the type of the property you will be searching for, you could use expressions.

如果您知道要搜索的属性的类型,则可以使用表达式。

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. 

I would probably wrap this up in a static class, like this:

我可能会将它包装在一个静态类中,如下所示:

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

that way you can write your selector like:

这样你就可以编写你的选择器:

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

That seems a bit more clear to me what it is I'm doing, especially if I'm reading expression DOM code I wrote 6 months after.

这对我来说似乎更清楚我正在做什么,特别是如果我正在阅读我在6个月后写的表达DOM代码。

#5


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