Dav*_*vid 2 c# linq predicate c#-4.0
我正在尝试创建一个 linq 扩展方法,该方法返回选定节点的路径。
到节点 Item4 的路径将产生 -{ Item1, Item2, Item4 }
到节点 Item3 的路径将产生 -{ Item1, Item3 }
public class Item
{
public int Id { get; set; }
public IList<Item> Items { get; set; }
}
Item1
Item2
Item4
Item3
Run Code Online (Sandbox Code Playgroud)
调用代码
var path = myItem.Items
.Path(e => e.Items, e => MyPredicateCondition())
.ToList();
Run Code Online (Sandbox Code Playgroud)
扩展方法
public static IEnumerable<T> Path<T>(
this IEnumerable<T> source,
Func<T, IEnumerable<T>> childrenSelector,
Predicate<T> condition)
{
if (source == null || !source.Any()) return default(T);
var attempt = source.FirstOrDefault(t => condition(t));
if (!Equals(attempt, default(T))) return attempt;
var items = source.SelectMany(childrenSelector)
.Path(childrenSelector, condition)
.ToList();
return attempt;
}
Run Code Online (Sandbox Code Playgroud)
我的问题不是找到实际的节点,而是返回节点递归地将树备份到根节点。数据结构应该保持原样 - 即我不希望引用Item它parent item。
注意:代码当前无法编译,因为我尝试通过其他方式使用 IEnumerable 产量等。
效率不是问题,因为它将用于 3 或 4 层深度,每个层仅包含几个项目。
这是一个基于简单的Stack实现。
这个想法是将我们要检查的每个项目放在一个堆栈上,如果它不是我们正在寻找的路径的一部分,则将其从堆栈中删除,直到找到我们正在寻找的项目。
IEnumerable<T> Path<T>(IEnumerable<T> source,
Func<T, IEnumerable<T>> childrenSelector,
Func<T, bool> condition)
{
var path = new Stack<T>();
Path(source, childrenSelector, condition, path);
return path.Reverse().ToList();
}
bool Path<T>(IEnumerable<T> source,
Func<T, IEnumerable<T>> childrenSelector,
Func<T, bool> condition,
Stack<T> path)
{
foreach (var item in source)
{
path.Push(item);
if (condition(item) || Path(childrenSelector(item), childrenSelector, condition, path))
return true;
else
path.Pop();
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
例子:
Item[] items = { new Item {Id = 1, Items = new List<Item>
{
new Item {Id = 2, Items = new List<Item> {new Item { Id = 4, Items = new List<Item>()}}},
new Item {Id = 3, Items = new List<Item>()},
}}};
var path = Path(items, e => e.Items, e => e.Id == 4);
// prints '1 -> 2 -> 4'
Console.WriteLine(String.Join(" -> ", path.Select(i=>i.Id)));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1512 次 |
| 最近记录: |