如果子列表包含Linq的特定对象,则设置值

时间:2017-07-11 16:45:22

标签: c# .net linq

我有元素列表

List<Element>() list;

Element的类定义如下:

public class Element
{
   public bool IsActive {get; set; }
   public string Name { get; set; }
   public List<Element> SubElements { get; set; }
}

此列表包含信息

[{
 IsActive: false;
 Name: "A";
 SubElements:
      [{
        IsActive: false;
        Name: "B";
        SubElements: null;
      },
      {
        IsActive: false;
        Name: "C";
        SubElements: null;
      }]
},
{
 IsActive: false;
 Name: "D";
 SubElements:
      [{
        IsActive: false;
        Name: "E";
        SubElements: null;
      },
      {
        IsActive: false;
        Name: "F";
        SubElements: null;
      }]
}] 

问题是如何通过IsActive名称将SubElement设置为此结构的第一级和第二级

例如,如果我得到“B”,带有Name = "B";的元素及其父元素应该有IsActive = true;

我知道如何使用foreach循环,但是可以使用Linq吗?

2 个答案:

答案 0 :(得分:0)

在不修改Element课程的情况下,我不相信您所描述的行为可以使用LINQ。但是,您可以使用List<T>.ForEach,同时使用LINQ&#39; Enumerable.Any<TSource>

// for each Element e in list
list.ForEach(e =>
{
    // if any sub-Element e1 in element e has Name == "B"
    if (e.SubElements.Any(e1 => e1.Name == "B"))
    {
        // set Element e.IsActive = true
        e.IsActive = true;

        // for each sub-Element e1 in Element e, set e1.IsActive = true
        e.SubElements.ForEach(e1 => e1.IsActive = true);
    }
});

答案 1 :(得分:0)

LINQ不是为修改数据而是为了查询和转换数据而设计的。您可以使用修改后的Element集创建列表的新副本:

public static List<Element> MakeActivatedList(List<Element> list, string activeName) {
    return list.Select(e => (e.Name == activeName || (e.SubElements != null && e.SubElements.Any(e1 => e1.Name == activeName))) ? new Element { IsActive = true, Name = e.Name, SubElements = (e.SubElements == null) ? null :  MakeActivatedList(e.SubElements, activeName) } : e).ToList();
}

但是如果你真的想在原始列表中设置值,则不应该使用LINQ:

public static void SetActive(List<Element> list, string activeName) {
    foreach (var e in list) {
        if (e.Name == activeName || (e.SubElements != null && e.SubElements.Any(e1 => e1.Name == activeName)))
            e.IsActive = true;
        if (e.SubElements != null)
            SetActive(e.SubElements, activeName);
    }
}