如果子列表包含具有 Linq 的特定对象,则设置值
Set value if sublist contain specific object with Linq
我有元素列表
List<Element>() list;
Class 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;
}]
}]
问题是如何通过SubElement
名称为该结构的第一层和第二层设置IsActive
为真?
例如,如果我得到 "B",具有 Name = "B";
的元素及其父元素应该具有 IsActive = true;
我知道如何用 foreach 循环来做,但是可以用 Linq 来做吗?
在不修改 Element
class 的情况下,我认为使用 LINQ 无法实现您描述的行为。但是,您可以使用 List<T>.ForEach
, while utilizing LINQ's 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);
}
});
LINQ 不是为修改数据而设计的,而是为查询和转换数据而设计的。您可以使用修改后的 Element
s 集创建列表的新副本:
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);
}
}
我有元素列表
List<Element>() list;
Class 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;
}]
}]
问题是如何通过SubElement
名称为该结构的第一层和第二层设置IsActive
为真?
例如,如果我得到 "B",具有 Name = "B";
的元素及其父元素应该具有 IsActive = true;
我知道如何用 foreach 循环来做,但是可以用 Linq 来做吗?
在不修改 Element
class 的情况下,我认为使用 LINQ 无法实现您描述的行为。但是,您可以使用 List<T>.ForEach
, while utilizing LINQ's 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);
}
});
LINQ 不是为修改数据而设计的,而是为查询和转换数据而设计的。您可以使用修改后的 Element
s 集创建列表的新副本:
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);
}
}