【问题标题】:scroll the list until you find the object with the corresponding id - C#滚动列表,直到找到具有相应 id 的对象 - C#
【发布时间】:2016-02-26 10:15:52
【问题描述】:

我有一个这样的列表(已经用 Visual Studio 调试器打开):

如您所见,该列表由相同类型列表的其他对象组成,我需要遍历所有子对象,而不考虑索引并验证 FID该对象的 em> 与 UI 传递的对象相同。一旦找到返回相同对象的匹配服务器。

我可以试试这个进行测试, 但考虑到我只有顶级项目,那些索引为 0 的项目,并没有全部流动:

AttachmentFolders childWithId17 = ApplicationContext.Instance.companyList[0].AttachmentFolders.SelectMany(parent => parent.AttachmentFolder)
                             .FirstOrDefault(child => child.FID == "835A09A2-9D60-46CC-A2BE-D4CBC4C81860");

另一张图更好理解

事实上,我得到了一个包含许多元素的列表,并且应该滚动所有元素,即使以响应方式能够返回与该 AttachmentFolders 对应的对象FID .

类结构:

public class AttachmentFolders
    {
        public int id { get; set; }
        public String FID { get; set; }
        public String Name { get; set; }
        public String CPID { get; set; }
        public String ParentFID { get; set; }

            public List<Attachment> Attachments { get; set; }
            public List<AttachmentFolders> AttachmentFolder { get; set; }
        }

public class Attachment
    {
        public int id { get; set; }
        public String ATID { get; set; }
        public String Name { get; set; }
        public String CreatorID { get; set; }
        public String FID { get; set; }
        public String Extension { get; set; }
        public String Description { get; set; }
        public int Status { get; set; }
        public String CPID { get; set; }
        public int FileSize { get; set; }
        public DateTime CreationDate { get; set; }
        public DateTime ModifiedDate { get; set; }
        public int AttachmentType { get; set; }
        public int ValidityType { get; set; }
        public List<Revisions> Revisions { get; set; }
        public String AWID { get; set; }
        public String WAID { get; set; }
        public String WatermarkPositions { get; set; }
        public Boolean Serveroffline { get; set; }
        public Boolean IsFavourite { get; set; }
        public DateTime LastOpenDate { get; set; }
        public int Priority { get; set; }
        public String CreatorFirstName { get; set; }
        public String CreatorLastName { get; set; }
        public String ModifiedByFirstName { get; set; }
        public String ModifiedByLastName { get; set; }
        public String[] Capabilities { get; set; }
    }

谢谢大家。

【问题讨论】:

  • 我无法重新创建您的班级结构。您能告诉我们您的课程是如何设计的吗?
  • 我已经添加了结构的两个类,谢谢

标签: c# list recursion parent-child


【解决方案1】:

您可以编写类似 SelectDeep 扩展名的内容,如 Marc 的回答:Expressing recursion in LINQ

然后在你的代码中使用它而不是SelectMany:

AttachmentFolders child = companyList[0].AttachmentFolders
    .SelectDeep(parent => parent.AttachmentFolder)
    .FirstOrDefault(child => child.FID == "835A09A2-9D60-46CC-A2BE-D4CBC4C81860");

SelectDeep 方法如下所示:

public static class EnumerableExtensions
{
    public static IEnumerable<T> SelectDeep<T>(
        this IEnumerable<T> source, Func<T, IEnumerable<T>> selector) {
        foreach (T item in source) {
            yield return item;
            foreach (T subItem in SelectDeep(selector(item), selector)) {
                yield return subItem;
            }
        }
    }
}

【讨论】:

  • 如何添加 SelectDeep ?我在 Visual Studio 中没有定义
  • 见谅,不过代码看不懂,也就是怎么申请,能说清楚吗?
  • @Mr.Developer 函数SelectDeep 的定义在我的回答中。您可以使用它从嵌套结构(树)中返回所有项目。只需使用此函数而不是 SelectMany
  • 我在 SelectDeep 上遇到此错误:扩展方法必须在顶级静态类中定义; EnumerableExtensions 是一个嵌套类,如何解决?如果可以的话,谢谢
  • @Mr.Developer 您不能将EnumerableExtensions 类放在另一个类中。它必须放在顶层,在任何类之外。
【解决方案2】:

这是一个典型的递归案例。您可以尝试搜索扁平的树结构,如 thisthis 答案中所做的那样。

如果您遇到此解决方案的性能缓慢,我会考虑创建一个帮助器 Dictionary&lt;string, AttachmentFolders&gt; 对象,该对象将保存所有(子)文件夹引用以便快速访问,例如

IEnumerable<AttachmentFolders> Flatten(AttachmentFolders f)
{
    var fs = new[] { f };
    return f.Children == null? fs : fs.Concat(f.Children.SelectMany(Flatten));
}

Dictionary<string, AttachmentFolders> GenerateCache(AttachmentFolders firstFolder)
{
    return Flatten(firstFolder).ToDictionary(f => f.FID, f => f);
}

然后,在开始时一次性:

Dictionary<string, AttachmentFolders> Cache = GenerateCache(firstFolder);

并且每次发出请求时:

if(Cache.ContainsKey(fid)) return Cache[fid];
else throw new Exception("Handle not found FID here");

【讨论】:

  • GenerateCache 是什么?
  • 类似于我现在编辑到我的答案中的函数。
  • 它也有效,但我更喜欢使用@romanoza 解决方案,它对我的​​情况有更多的扩展。谢谢你的帮助。我会告诉你答案。
猜你喜欢
  • 2010-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-19
  • 2016-01-28
  • 2011-12-16
  • 2015-02-17
相关资源
最近更新 更多