【问题标题】:Find an item in a list在列表中查找项目
【发布时间】:2014-08-10 03:19:52
【问题描述】:

在 C# 中,如果我有一个对象列表,其中每个列表都有一个列表项列表,并且这些列表项中的每一个都可以是一个对象列表(或只是一个列表项),那么最好的方法是什么?按名称检索特定列表?

每个列表和列表项都有一个唯一的名称。 MapLocationListItem 中的 type 属性是“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;}
}

提前致谢

【问题讨论】:

  • 尝试使用 Linq 并指定需要查找的项目
  • 你的模型对我来说有点奇怪,你的MapLocationList 有一个MapLocationListItem 的列表,其中有一个MapLocationLists 的列表?

标签: c# list object search recursion


【解决方案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);
    }
}

所以,现在我们有了List&lt;MapLocationList&gt;,我们只需要创建一个函数来获取任何给定节点的所有子项,以使用我们的Traverse 方法。如果我们只有一种类型的节点,我们将直接获取所有子节点。由于我们有两种类型,所以我们需要使用SelectMany 来获取我们子节点的子节点:

var allNodes = rootNodes.Traverse(mapLocations => 
    mapLocations.listItems.SelectMany(item => item.list));

从这里我们可以很容易地得到第一个具有给定名称的项目:

var servyNode = allNodes.FirstOrDefault(node => node.name == "Servy");

【讨论】:

    【解决方案2】:

    你可以使用 Linq :

       var res = from item in listItems
                 where item.Name equals "yourentry"
                 select item;
    

    或者简单地说:

    MapLocationListItem findRes = listItems.Where(x => x.name.Equals(yourentry)).FirstOrDefault();
    

    【讨论】:

    • 我相信提问者也想通过 MapLocationListItem 中包含的所有列表进行递归......
    【解决方案3】:

    找到下面的解决方案,这将找到并返回 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; }
        }
    

    【讨论】:

    • 我相信提问者也想递归遍历MapLocationListItem 中包含的所有列表......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 2021-12-24
    • 2023-03-11
    • 1970-01-01
    • 2014-10-13
    • 2023-02-11
    相关资源
    最近更新 更多