在过滤的递归列表中包含父项
Include parents in filtered recursive list
目标是过滤递归列表。当用户搜索 Bar 时,应显示 Foo -> Bar。同样,当搜索词是 Baz 时,Foo -> Bar -> Baz 应该包含在结果中。
我的想法是遍历结果并将父项(如果有)添加到结果中。但这必须以递归方式完成。是否有使用 linq 的更简单的解决方案?你有什么想法?
我尝试过的:
游乐场:https://try.mudblazor.com/snippet/GaGQYokTnQPmRIHO
Main.razor
<MudTextField
T="string"
DebounceInterval="500"
Clearable="true"
Placeholder="Search"
Margin="Margin.Dense"
Variant="Variant.Outlined"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Filled.Search"
ValueChanged="@(s => SearchTerm = s)"/>
<CascadingValue Value="Items.Where(i => (!string.IsNullOrEmpty(SearchTerm)) ? i.Name.Contains(SearchTerm) : true).ToArray()">
<ItemList Parent="0"/>
</CascadingValue>
@code {
public string? SearchTerm { get; set; } = string.Empty;
public Item[]? Items =
{
new Item { Id = 1, Name = "Foo", Parent = 0 },
new Item { Id = 2, Name = "Bar", Parent = 1 },
new Item { Id = 3, Name = "Baz", Parent = 2 },
};
}
ItemList.razor
@foreach(var item in Items.Where(i => i.Parent == Parent))
{
@if (Items.Where(i => i.Parent == item.Id).Any())
{
<MudNavGroup Title="@item.Name">
<ItemList Parent="@item.Id"/>
</MudNavGroup>
}
else
{
<MudNavLink Href="@("/items/" + item.Id)">@item.Name</MudNavLink>
}
}
@code {
[Parameter] public int? Parent { get; set; }
[CascadingParameter] public Item[]? Items { get; set; }
}
Item.cs
public class Item
{
public int Id { get; set; }
public string? Name { get; set; }
public int? Parent { get; set; }
}
您可以添加函数 Filter
或在 @code
中使用适当的名称,如下所示。并更新 <CascadingValue Value="Filter(SearchTerm)">
解释在评论中。
<CascadingValue Value="Filter(SearchTerm)">
<ItemList Parent="0"/>
</CascadingValue>
public Item[] Filter(string SearchTerm)
{
// Get filtered list. Return all values when SearchTerm is null or empty else return matching values only
var a = Items.Where(i => string.IsNullOrEmpty(SearchTerm) || i.Name.Contains(SearchTerm)).ToList();
// NOTE : Add children first then only search for parent
// Use condition to find all children hierarchy of any object which is not exist in the list
while (Items.Any(i => a.Any(x => x.Id == i.Parent) && !a.Any(x => x.Id == i.Id)))
{
// Add complete children hierarchy for selected iterms
a.AddRange(Items.Where(i => a.Any(x => x.Id == i.Parent) && !a.Any(x => x.Id == i.Id)));
}
// Use condition to find parent of any object which is not exist in the list
while (Items.Any(i => a.Any(x => x.Parent == i.Id) && !a.Any(x => x.Id == i.Id)))
{
// Add all parents who are not already added in list
a.AddRange(Items.Where(i => a.Any(x => x.Parent == i.Id) && !a.Any(x => x.Id == i.Id)));
}
// return final object
return a.ToArray();
}
目标是过滤递归列表。当用户搜索 Bar 时,应显示 Foo -> Bar。同样,当搜索词是 Baz 时,Foo -> Bar -> Baz 应该包含在结果中。
我的想法是遍历结果并将父项(如果有)添加到结果中。但这必须以递归方式完成。是否有使用 linq 的更简单的解决方案?你有什么想法?
我尝试过的:
游乐场:https://try.mudblazor.com/snippet/GaGQYokTnQPmRIHO
Main.razor
<MudTextField
T="string"
DebounceInterval="500"
Clearable="true"
Placeholder="Search"
Margin="Margin.Dense"
Variant="Variant.Outlined"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Filled.Search"
ValueChanged="@(s => SearchTerm = s)"/>
<CascadingValue Value="Items.Where(i => (!string.IsNullOrEmpty(SearchTerm)) ? i.Name.Contains(SearchTerm) : true).ToArray()">
<ItemList Parent="0"/>
</CascadingValue>
@code {
public string? SearchTerm { get; set; } = string.Empty;
public Item[]? Items =
{
new Item { Id = 1, Name = "Foo", Parent = 0 },
new Item { Id = 2, Name = "Bar", Parent = 1 },
new Item { Id = 3, Name = "Baz", Parent = 2 },
};
}
ItemList.razor
@foreach(var item in Items.Where(i => i.Parent == Parent))
{
@if (Items.Where(i => i.Parent == item.Id).Any())
{
<MudNavGroup Title="@item.Name">
<ItemList Parent="@item.Id"/>
</MudNavGroup>
}
else
{
<MudNavLink Href="@("/items/" + item.Id)">@item.Name</MudNavLink>
}
}
@code {
[Parameter] public int? Parent { get; set; }
[CascadingParameter] public Item[]? Items { get; set; }
}
Item.cs
public class Item
{
public int Id { get; set; }
public string? Name { get; set; }
public int? Parent { get; set; }
}
您可以添加函数 Filter
或在 @code
中使用适当的名称,如下所示。并更新 <CascadingValue Value="Filter(SearchTerm)">
解释在评论中。
<CascadingValue Value="Filter(SearchTerm)">
<ItemList Parent="0"/>
</CascadingValue>
public Item[] Filter(string SearchTerm)
{
// Get filtered list. Return all values when SearchTerm is null or empty else return matching values only
var a = Items.Where(i => string.IsNullOrEmpty(SearchTerm) || i.Name.Contains(SearchTerm)).ToList();
// NOTE : Add children first then only search for parent
// Use condition to find all children hierarchy of any object which is not exist in the list
while (Items.Any(i => a.Any(x => x.Id == i.Parent) && !a.Any(x => x.Id == i.Id)))
{
// Add complete children hierarchy for selected iterms
a.AddRange(Items.Where(i => a.Any(x => x.Id == i.Parent) && !a.Any(x => x.Id == i.Id)));
}
// Use condition to find parent of any object which is not exist in the list
while (Items.Any(i => a.Any(x => x.Parent == i.Id) && !a.Any(x => x.Id == i.Id)))
{
// Add all parents who are not already added in list
a.AddRange(Items.Where(i => a.Any(x => x.Parent == i.Id) && !a.Any(x => x.Id == i.Id)));
}
// return final object
return a.ToArray();
}