linq 从列表中删除项目并重新排列

myzjeezk  于 2022-12-06  发布在  其他
关注(0)|答案(2)|浏览(137)

我有一个包含字符串的order属性的列表。
数据如下所示:

1
2
    2.1
        2.1.1
        2.1.2
    2.2
        2.2.1
        2.2.2
3
    3.1
    3.2
    3.3
4

阶级结构是这样的

public class CMNavBarDefaultDto
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string? Description { get; set; }
    public string? Comments { get; set; }
    public string Order { get; set; }
    public bool ToShowGray { get; set; }
    public bool IsNew { get; set; }
}

如果用户从列表中删除任何顺序,如用户删除3.1,则3.2和3.3重新排列,3.2变成3.1,3.3变成3.1,如果用户删除任何父,如1,则所有的分层结构应该以新的形式保持,如2变成1,并且它的孩子和子孩子应该从1开始。
有人能告诉我在这种情况下什么方法是有帮助的吗?

kh212irz

kh212irz1#

在我看来,最好的方法是使用uint列表来指定所需的级别。然后,您可以将html表与Order对象并行,以便通过让删除操作实际修改Order来根据需要更新表,然后Order更新html表。
问题是,如果用户删除了中间层,该怎么办?例如,如果用户按以下顺序删除1.1,1.1.1和1.1.2会发生什么?

1
  1.1
    1.1.1
    1.1.2
  1.2

难道就变成下面这样了?

1
  1.1
  1.2
  1.3 (was 1.2)

了解了这些规则,您可以创建一个转换函数来创建并行Order,然后根据需要对其进行操作。(即,如果您的级别为2,则假定之前的级别为2或1)。在任何时候,您都可以向上跳转级别(也就是说,你可能在第4级,然后有下一个第1级)。如果你不遵守这些规则,ToString函数将抛出Exception。

public class Order
{
    var list = new List<unit>();

    // needed: static function or constructor that takes html table string and returns Order and methods to modify Order

    public override string ToString()
    {
        var sb = new StringBuilder();
        var stack = Stack<(uint, string))>();
        uint current = 0;
        string order = "";
        foreach (var next in list)
        {
            if (next > stack.Count)
            {
                // next is in deeper level, make sure prior level(s) exist.
                if ((current == 0) || (next != (stack.Count + 1))) throw new Exception("missing level");

                // prior level(s) exist, push current level in stack in case lower level needed later, then restart count within next level
                stack.Push((current, order));
                order = $"{order}{current}.";
                current = 0;
            }
            else if (next < stack.Count)
            {
                // at lower level! pop out levels from stack until we get back to next level
                while (stack.Count > next)
                {
                    (current, order) = stack.Pop();
                }
            }

            // append next level to output
            current++;
            sb.AppendLine($"{order}{current}");
        }
        return sb.ToString();
    }
}
sz81bmfz

sz81bmfz2#

以下内容将创建树。必须添加代码才能在树中添加和移除项。添加或移除时,必须对项重新编号

using System;
using System.Linq;
using System.Text;
using System.Collections;
using System.Collections.Generic;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            List<CMNavBarDefaultDto> list = new List<CMNavBarDefaultDto>()
            {
                new CMNavBarDefaultDto() { Order = "1"},
                new CMNavBarDefaultDto() { Order = "2"},
                new CMNavBarDefaultDto() { Order = "2.1"},
                new CMNavBarDefaultDto() { Order = "2.1.1"},
                new CMNavBarDefaultDto() { Order = "2.1.2"},
                new CMNavBarDefaultDto() { Order = "2.2"},
                new CMNavBarDefaultDto() { Order = "2.2.1"},
                new CMNavBarDefaultDto() { Order = "2.2.2"},
                new CMNavBarDefaultDto() { Order = "3"},
                new CMNavBarDefaultDto() { Order = "3.1"},
                new CMNavBarDefaultDto() { Order = "3.2"},
                new CMNavBarDefaultDto() { Order = "3.3"},
                new CMNavBarDefaultDto() { Order = "4"},
            };

            Tree root = new Tree();
            root.MakeTree(list, root);
        }
    }
    public class CMNavBarDefaultDto
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string? Description { get; set; }
        public string? Comments { get; set; }
        public string Order { get; set; }
        public bool ToShowGray { get; set; }
        public bool IsNew { get; set; }
    }
    public class Tree 
    {
        public CMNavBarDefaultDto cmNav { get; set; }
        public int[] orderInt { get; set; }
        public List<Tree> children { get; set; }

        public void MakeTree(List<CMNavBarDefaultDto> cmNavs, Tree parent)
        {
            List<Tree> list = new List<Tree>();
            foreach(CMNavBarDefaultDto cmNav in cmNavs)
            {
                Tree node = new Tree() { cmNav = cmNav, orderInt = cmNav.Order.Split(new char[] { '.' }).Select(x => int.Parse(x)).ToArray() };
                list.Add(node);
            }
            int level = 0;
            list = list.OrderBy(x => x.orderInt.Length).ToList();
            MakeTreeRecursive(list, parent, level);
        }
        public void MakeTreeRecursive(List<Tree> list, Tree parent, int level)
        {
            var groups = list.GroupBy(x => x.orderInt[level]).ToList();
            foreach(var group in groups)
            {
                if (parent.children == null) parent.children = new List<Tree>();
                parent.children.Add(group.First());
                if (group.Count() > 1)
                {
                    if (group.Last().orderInt.Length == level + 1)
                    {
                        group.First().children = new List<Tree>();
                        group.First().children = group.Skip(1).ToList();
                    }
                    else
                    {
                        MakeTreeRecursive(group.Skip(1).ToList(), group.First(), level += 1);
                    }
                }
            }
        }

    }
}

相关问题