【问题标题】:Filter a generic list based on another list根据另一个列表过滤通用列表
【发布时间】:2014-02-19 10:45:37
【问题描述】:

我有一个通用列表,需要根据另一个列表(例如,List<string>)进行过滤。

public class Model
{
  public string ID { get; set;}
  public string Make { get; set;}
}

List<Model> lstModel = new List<Model>();

而lstModel如下

 ID      Make
----    -----------
 5       MARUTI
 4       BENZ
 3       HYUNDAI
 2       HONDA
 1       TOYOTA

我还有另一个列表,其中仅包含汽车制造商,即

List<string> lstMakers = new List<string>() {"MARUTI", "HONDA"};

1) 我需要过滤仅包含 lstMakers 中的项目的 lstModel。 输出将是

 ID      Make
----    -----------
 5       MARUTI
 2       HONDA

2) 基于输出 (1),需要另一个 id 列表,每个项目按降序递增 1, 输出将是List&lt;int&gt; 即,

  6
  5
  3
  2

注意:使用 lambda 表达式 / linq 更可取

【问题讨论】:

    标签: c# linq lambda


    【解决方案1】:

    1)

    var list1 = lst.Where(x=>lstMakers.Contains(x.Make)).ToList();
    

    2)

    var list2 = list1.Select(x=>int.Parse(x.ID)+1)
                     .Concat(list1.Select(x=>int.Parse(x))
                     .OrderByDescending(x=>x)
                     .ToList();
    

    【讨论】:

    • 关于第一个输出:而不是“包含”,是否可能 x=>lstMakers.Equals(x.Make) 关于第二个输出:它只返回增量值,但我需要项目和它的增量值,例如,我将得到 6、5、3、2。这里 5 和 2 是原始项目,6 和 3 是其增量值。总共 4 项。
    • 不,这是不可能的,因为当您调用 lstMakers.Equals(x.Make) 时,您应该将 List 类型的参数传递给 Equals,就像 lstMakers 的类型一样。请检查此msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx
    • 关于第二个输出:它只返回增量值,但我需要项目和它的增量值,所以例如我会得到 6,5,3,2。这里 5 和 2 是原始项目,6 和 3 是其增量值。总共 4 项。
    • 试试第二个版本,我刚写的请告诉我。
    • 我在新的一天调试它时理解了这段代码。没关系。我也对您的答案投了赞成票,因为我已经将另一个答案标记为已接受的答案。 :)。这两个答案都给出了与我预期相同的结果。
    【解决方案2】:

    使用Enumerable.JoinOrderByDescending

    var models = from maker in lstMakers
                 join model in lstModel
                 on maker equals model.Make
                 select model;
    List<int> result = models
        .Select(m => int.Parse(m.ID) + 1)
        .OrderByDescending(i => i)
        .ToList();
    

    但是,这会选择两个ints,因为只有两个模型匹配。您的结果包含 4 个ints。我假设您的结果与您的样本无关,是吗?

    但我需要该项目及其增量值,...

    现在很清楚,将Enumerable.SelectMany 与数组一起使用:

    List<int> result = models
        .Select(m => int.Parse(m.ID))
        .SelectMany(id => new int[]{ id, id + 1 })
        .OrderByDescending(id => id)
        .Distinct()
        .ToList();
    

    【讨论】:

    • 在 Select 语句之后添加第二个 lambda 表达式 .Concat(models.Select(x=>int.Parse(x))) 给出了我预期的结果。请据此更正 lambda。感谢@Christos Paisios
    • @SanoojVS:使用SelectMany,我已经编辑了我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    相关资源
    最近更新 更多