#c# #list #object #search #recursion
#c# #Список #объект #Поиск #рекурсия
Вопрос:
В C #, если у меня есть список объектов, где каждый список содержит список элементов списка, и каждый из этих элементов списка может быть списком объектов (или просто одним элементом списка), каков наилучший способ получения определенного списка по имени?
Каждый список и элемент списка имеют уникальное имя. Атрибутом типа в MapLocationListItem
является либо «List», либо «ListItem».
Вот классы:
public class MapLocationList
{
public string name { get; set; }
public List<MapLocationListItem> listItems { get; set;}
public MapLocationList ()
{
listItems = new List<MapLocationListItem> ();
}
}
public class MapLocationListItem
{
public string name { get; set;}
public string type { get; set;}
public string heading { get; set;}
public string subheading { get; set;}
MapLocationList mapLocationList{ get; set;}
}
Заранее спасибо
Комментарии:
1. попробуйте использовать Linq и укажите, какой элемент вам нужно найти
2. Ваша модель выглядит немного странно для меня, у вас
MapLocationList
есть списокMapLocationListItem
‘s, в котором есть списокMapLocationList
s?
Ответ №1:
То, что у вас здесь есть, — это дерево (с двумя типами узлов) (также предполагая, что у вас нет циклов, что сделало бы его графом). Обход дерева — довольно простая задача, которую мы можем решить в общем случае всего несколькими строками кода:
public static IEnumerable<T> Traverse<T>(
this IEnumerable<T> source
, Func<T, IEnumerable<T>> childrenSelector)
{
var stack = new Stack<T>(source);
while (stack.Any())
{
var next = stack.Pop();
yield return next;
foreach (var child in childrenSelector(next))
stack.Push(child);
}
}
Итак, теперь, когда у нас есть a List<MapLocationList>
, все, что нам нужно, это создать функцию, которая заставит все дочерние элементы любого данного узла использовать наш Traverse
метод. Если бы у нас был только один тип узла, мы бы просто получили все дочерние узлы напрямую. Поскольку у нас есть два типа, нам нужно использовать SelectMany
для получения дочерних элементов наших дочерних узлов:
var allNodes = rootNodes.Traverse(mapLocations =>
mapLocations.listItems.SelectMany(item => item.list));
Отсюда мы можем легко получить первый элемент с заданным именем:
var servyNode = allNodes.FirstOrDefault(node => node.name == "Servy");
Ответ №2:
Найдите решение, как показано ниже, оно найдет и вернет MapLocationListItem в противном случае null (если не найдено)
public class MapLocationList
{
public string name { get; set; }
public List<MapLocationListItem> listItems { get; set; }
public MapLocationList()
{
listItems = new List<MapLocationListItem>();
}
public MapLocationListItem findByName(string locationName)
{
MapLocationListItem findRes = listItems.Where(x => x.name.Equals(locationName)).FirstOrDefault();
return findRes;
}
}
public class MapLocationListItem
{
public string name { get; set; }
public string type { get; set; }
public string heading { get; set; }
public string subheading { get; set; }
MapLocationList list { get; set; }
}
Комментарии:
1. Я полагаю, что запрашивающий также хочет выполнить повторный просмотр всех содержащихся в нем списков
MapLocationListItem
…
Ответ №3:
вы можете использовать Linq :
var res = from item in listItems
where item.Name equals "yourentry"
select item;
или просто :
MapLocationListItem findRes = listItems.Where(x => x.name.Equals(yourentry)).FirstOrDefault();
Комментарии:
1. Я полагаю, что запрашивающий также хочет выполнить повторный просмотр всех содержащихся списков в MapLocationListItem..