【问题标题】:c# Insert item in nested list of objectsc#在嵌套的对象列表中插入项目
【发布时间】:2018-08-16 12:26:17
【问题描述】:

我有这样的课:

public class Abc
{   
    public int Id { get; set; }
    public List<Abc> Child{ get; set; }
}

我有一个这样的 Abc 嵌套列表,其中包含两个父项及其子项:

Abc (Id = 1)
|
|-- Abc (Id = 2)
|-- Abc (Id = 3)
     |
     |-- Abc (Id = 4)
          |
          |-- Abc (Id =5)
Abc (Id = 6)
|
|-- Abc (Id = 7)
|-- Abc (Id = 8)
     |
     |-- Abc (Id = 9)
          |
          |-- (Id = 10)

==== 更新 ====

话虽如此,我有两个输入参数:

  1. ID = 4
  2. Abc 类 (Id = 9) 的对象
  3. Abc 类的对象 (Id = 11)

我需要在整个列表中找出 id 为 4 的对象,并且仅当列表中不存在该对象时才将该对象插入其子项中。

所以 id = 9 已经存在,所以我不能插入。但我可以插入 Id = 11 的对象。

=== 更新 2 ====
所以添加 id = 11 后,列表应该是这样的。

Abc (Id = 1)
|
|-- Abc (Id = 2)
|-- Abc (Id = 3)
     |
     |-- Abc (Id = 4)
          |
          |-- Abc (Id =5)
          |-- Abc (Id = 11) -- ADDED
Abc (Id = 6)
|
|-- Abc (Id = 7)
|-- Abc (Id = 8)
     |
     |-- Abc (Id = 9)
          |
          |-- (Id = 10)

我不知道如何实现这一点。 有人可以帮忙吗?它可以是 c# lambda 或 linq 或任何其他方法。

【问题讨论】:

  • 这是你经常做的事情还是只会做一次?如果您这样做一次,那么仅递归您的列表可能就是要走的路。如果您经常这样做,那么您可能希望以 id 作为键存储您的 ABC 字典,这样您可以在获得特定 ABC 的 id 时非常快速地找到它。
  • 如果您能向我们展示您的尝试并指出您面临的问题,我们会更容易为您提供帮助。
  • 大家好,我刚刚更新了需求。请参阅更新下的部分。很抱歉错过了。
  • 对此有什么帮助吗?应始终在整个列表中搜索 id。

标签: c# list linq lambda nested


【解决方案1】:

当然,您可以检查 Child 属性不为 null 的位置。

public class Abc
{
    public Abc(int id)
    {
        Id = id;
    }

    public int Id { get; }
    public List<Abc> Child { get; set; }

    public Abc FindById(int id)
    {
        if (Id == id) return this;
        if (Child == null) return null;

        foreach (var childItem in Child)
        {
            var result = childItem.FindById(id);
            if (result != null) return result;
        }

        return null;
    }

    public bool HasChild(int id)
    {
      return FindById(id) != null;
    }

    public Abc AddChildIfNotExist(Abc child)
    {
        if (child == null) return this;
        if (!HasChild(child.Id))Child.Add(child);
        return this;
    }
}

    static void Main(string[] args)
    {

        var a = new Abc(1)
        {
            Child = new List<Abc>
            {
                new Abc(2),
                new Abc(3)
                {
                    Child = new List<Abc>
                    {
                        new Abc(7)
                        {
                            Child = new List<Abc>
                            {
                                new Abc(5)
                            }
                        }
                    }
                },
                new Abc(6)
                {
                    Child = new List<Abc>
                    {
                        new Abc(8)
                        {
                            Child = new List<Abc>
                            {
                                new Abc(9),
                                new Abc(4)
                                {
                                   Child = new List<Abc>()
                                }
                            }
                        }
                    }
                }
            }
        };

        a
            .FindById(4)
            .AddChildIfNotExist(new Abc(10))
            .AddChildIfNotExist(new Abc(4));
    }

【讨论】:

  • +1 用于工作实施。但根据 OP 的嵌套列表,Abc Id = 6 不是Abc Id = 1 的子代。
  • 让我试试看。
  • 我试过了,它将孩子插入 id 4 但只返回该列表而不是整个列表。应该对整个列表进行更改。
  • “应该对整个列表进行更改”是什么意思?应该将孩子添加到所有嵌套列表中?
  • 嗨,我已经编辑了这个问题。请查看更新 2。
【解决方案2】:

尝试递归,应该可以正常工作。在每个成员处检查其 ID。如果它是您想要的 ID,只需将对象插入其子对象即可。如果不是,请检查它是否有孩子。如果没有,请转到下一个元素。如果是这样,请以与检查当前成员相同的方式检查其子项(这是递归的来源)。

为了练习,你可以自己写代码。如果它不起作用,请随时询问。

【讨论】:

  • 好的,让我试试,但我不确定如何在完成 Abc (Id = 1) 后到达 [Abc (Id = 6)],因为它们之间没有链接。
  • @Sandipan。你必须做一个 Foreach("Elements in the main list")
  • 您在每个级别所拥有的是一个列表。因此,在外部级别,您有一个由两个对象组成的列表:abc id=1 和 abc id=6。在每个 abc 对象中(如果它有子对象),您将拥有由 X 个 abc 成员组成的相同外观列表。所以你总是必须像@Maxter 所说的那样循环那个列表。如果有孩子,您可以再次调用该函数,或者如果在最内层找不到它,则只返回一些值(比如说false)。
  • @Sandipan 关于您的编辑:列表通过引用传递。所以真的,当你找到你需要的 ID 时,只需将你想要添加的对象添加到它的子列表中。您传递的列表将自动更新。如果您想在插入之前知道该对象是否已经存在,您还可以有两个单独的函数(以相同的方式查找元素,但执行不同的操作),其中一个检查对象是否存在,另一个插入。然后你检查它是否存在,如果不存在,尝试插入。
【解决方案3】:

类似的东西应该可以工作:

public void findIndex(Abc myClass)
{
    if(myClass.Id == 4)
    {
        //Insert the new item here in the children childs
    }
    else
    {
        Foreach(Abc children in myClass.Child)
        {
            findIndex(children)
        }
    }
}

【讨论】:

  • 这不会检查根级别 Abc 对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多