Linq选择:使用列表中的值(如果可用)

时间:2012-11-29 10:53:34

标签: c# linq

我将使用一些基本的精简示例来说明我的问题。

我有一个班级:

class Item
{
   int ID;
   bool Selected;
}

现在假设我有两个Item类列表:

List<Item> ListA = GetListA();
List<Item> ListB = GetListB();

现在我想创建一个包含ListB所有项目的第三个列表。重要的是,如果在ID中找到匹配项(相同ListA),那么我想使用该Selected值,否则我希望保留Selected值{ ListB中的项目。

我正在创建第三个列表,如下所示:

List<Item> ListC = from item in ListB 
select new Item
{
   ID = item.ID,
   Selected = item.Selected// <-- should use value form ListA if available
};

重要:我不想显得无知,但我想要改变创建ListC的方式。我的意思是我想使用“linq选择”方法,我想使用一个“一个班轮”来分配Selected值...我知道还有其他方法来创建列表,它将工作很好,但后来我不会学到任何新东西。


到目前为止,我尝试过几件事......

我知道这会有效,但我不想两次查询ListA

Selected = ListA.Any(x => x.ID == item.ID) ? ListA.First(x => x.ID == item.ID).Selected : item.Selected

并且我也尝试使用DeafultIfEmpty,但我认为这种情况并不合适......因为它不起作用,如果ListA它似乎更有用是空的(我不在乎)

2 个答案:

答案 0 :(得分:7)

您可以按如下方式修改最后一行代码:

Selected = (ListA.FirstOrDefault(x => x.ID == item.ID) ?? item).Selected;

对于DefaultIfEmpty,您必须执行

Selected = ListA.Where(x => x.ID == item.ID).DefaultIfEmpty(item)
                                                       .First().Selected;

更难以遵循,但基本上做同样的事情。

正如Dominic在下面提到的,如果您使用SingleOrDefault/Single代替FirstOrDefault/First,如果您在ListA中找到两个具有相同ID的项目,则会收到例外情况 - 这可能是您要介绍的支票。

更好/更有效的方法,但正如你所说,你想要修复这种的做法,而不是采用完全不同的方式。)

答案 1 :(得分:2)

这个怎么样?

var query = from b in ListB
        join a in ListA
            on b.ID equals a.ID into g
        from r in g.DefaultIfEmpty(b)
        select new Item { ID = b.ID, Selected = r.Selected };