#c# #list #object #recursion #find
#c# #Список #объект #рекурсия #Найти
Вопрос:
Какой наилучший способ в C # найти имя объекта, вложенного в список?
Вот мои классы:
public class ItemListGallery
{
public string name { get; set; }
public List<ItemList> ListItems { get; set; }
}
public class ItemList
{
public string name { get; set; }
public List<Item> items { get; set; }
}
public class Item
{
public string name { get; set; }
}
Если у меня есть List<ItemListGallery>
, и каждый элемент в List<ItemListGallery>
имеет List<ItemList>
, и каждый элемент в List<ItemList>
имеет Item
, и у меня есть name
значение, которое нужно найти, как я могу вернуть объект / список с определенным name
значением?
Каждый атрибут name уникален.
Я пытался написать какой-нибудь код поиска, но заблудился. Есть ли расширенная функция IEnumerable, которую я могу использовать, чтобы помочь в этой ситуации?
Могу ли я, пожалуйста, получить некоторую помощь с этим?
Заранее спасибо
Редактировать
Вот код поиска, который я пытаюсь написать, правильный ли это подход?
public class ItemListGallery
{
public string name { get; set; }
public List<ItemList> ListItems { get; set; }
public string Find(string name)
{
foreach (var item in ListItems)
{
if (item.Find(name) != null)
{
return name;
}
}
return null;
}
}
public class ItemList
{
public string name { get; set; }
public List<Item> items { get; set; }
public string Find(string name)
{
foreach (var item in items)
{
if (item.name != null)
{
return name;
}
}
return null;
}
}
public class Item
{
public string name { get; set; }
}
Комментарии:
1. Вы говорите, что написали какой-то код, но не предоставили им общий доступ. Обновите вопрос недостающим кодом.
2. Вы хотите найти ItemListGallery, содержащий список<ItemList>, в котором есть элемент с этим именем? Или вам нужен список<ItemList> ?
3. это имя, которое вы хотите отфильтровать, принадлежит вашему списку или элементу?
Ответ №1:
Вы можете расставить точки над ним двумя способами. Либо вы используете отражение, либо используете общий вспомогательный интерфейс. В любом случае, ListItems и items должны иметь одинаковое имя, чтобы обеспечить некоторую логику отношения.
public List<Item> ListItems { get; set; }
public List<ItemList> ListItems { get; set; }
Вот способ, которым вы можете сделать это с помощью общего интерфейса
public interface IItem
{
String Name { get; set; }
}
public interface IContainerItem
{
List<IItem > ListItems { get; }
}
Затем :
public class ItemListGallery : IContainerItem, IItem
.....
public class ItemList: IContainerItem, IItem
.....
public class Item : IItem
Тогда вот как вы можете получить его рекурсивно :
private static IItem DoSearch(List<IItem> rootItems, String name) {
foreach (var item in rootItems) {
if (item.Name == name){
return item ;
}
if (item is IContainerItem) {
var containerItem = (IContainerItem) item;
var result = DoSearch(containerItem .ListItems , name) ;
if (result != null) {
return result ;
}
}
}
return null ;
}
Ответ №2:
Самым простым в использовании является LINQ.
Задан параметр поиска с именем findStr
. Давайте предположим, что вы хотите найти любой ItemListGallery
объект с именем findStr
, или содержащий ItemList
объект с именем findStr
, или содержащий ItemList
, который содержит Item
named findStr
… вы можете сделать это таким образом:
var findqry =
(
from gal in galleryList
where
gal.name == findStr ||
gal.ListItems.Any(li =>
li.name == findStr ||
li.Items.Any(i => i.name == findStr)
)
select gal
);
Если вам нужен только один результат, findqry.FirstOrDefault()
мы предоставим его вам. Если вам нужны все результаты, findqry.ToList()
or findqry.ToArray()
вернет их все.
Обратите внимание, что выполнение этого в LINQ to Objects приведет к сравнениям с учетом регистра, как и при любом другом использовании ==
с string
s. LinqToSql, с другой стороны, будет выполнять сравнения с учетом или без учета регистра в зависимости от параметров сортировки сравниваемого поля / таблицы / базы данных.
Если вы хотите выполнять сравнения без учета регистра, используйте string.Compare(object.name, findStr, true) == 0
или аналогичный вместо object.name == findstr
.
Комментарии:
1. Было бы неплохо немного критики, если вы собираетесь отклонить ответ. Просто говорю.