【问题标题】:Rearrange generic list after sequence update in c#在 C# 中序列更新后重新排列通用列表
【发布时间】:2019-10-23 11:18:24
【问题描述】:

假设我有一个这样的通用列表:

var categories = new List<Category>() {
    new Category() { sequence = 3, categoryName = "Category F" },
    new Category() { sequence = 1, categoryName = "Category S" },
    new Category() { sequence = 2, categoryName = "Category Z" },
    new Category() { sequence = 4, categoryName = "Category X" },
    new Category() { sequence = 5, categoryName = "Category V" }
};

我正在尝试用另一个替换给定的序列号,即用序列号 2 更新列表中的项目,编号为 5,如下所示:

int currSeq = 2;
int newSeq = 5;
var item = categories.Find(a => a.sequence == currSeq);
item.sequence = newSeq;

如果 newSeq 没有​​重复,例如newSeq = 6,我可以做 OrderBy:

categories = categories.OrderBy(c => c.sequence).ToList();

但问题是当它们重复时,我需要 newSeq 成为序列#5 并碰撞另一个重复的序列#5 + 1。

请提供解决此问题的任何指导。谢谢。

更新:某些情况下,当新序列

场景 A:

var categories = new List<Category>() {
    new Category() { sequence = 3, categoryName = "Category F" },
    new Category() { sequence = 1, categoryName = "Category S" },
    new Category() { sequence = 2, categoryName = "Category Z" },
    new Category() { sequence = 5, categoryName = "Category X" },
    new Category() { sequence = 6, categoryName = "Category V" }
};
int currSeq = 2;
int newSeq = 1;
var result = categories.UpdateSequence(currSeq,newSeq).OrderBy(x=>x.sequence);

输出场景 A:

1: Category S
3: Category Z
4: Category F
5: Category X
6: Category V

所需的输出场景 A:

1: Category Z
2: Category S
3: Category F
5: Category X
6: Category V

场景 B:

int currSeq = 3;
int newSeq = 1;
var result = categories.UpdateSequence(currSeq,newSeq).OrderBy(x=>x.sequence);

输出场景 B:

1: Category Z
2: Category S
4: Category F
5: Category X
6: Category V

期望的输出场景 B:

1: Category F
2: Category S
3: Category Z
5: Category X
6: Category V

【问题讨论】:

  • 好吧,再次使用 Linq。首先确定您的 categories 列表是否具有与 newSeq 具有相同 sequence 编号的 Category 对象。如果不存在这样的 Category 对象,则不需要递增。否则,Select 从您的类别中列出 sequence 数字等于或大于 newSeqCategory 对象,然后递增那些 Category 对象的sequence。完成...

标签: c# .net list linq sorting


【解决方案1】:

按照 elgonzo 在他的评论中所说的去做。另外,从间隔较宽的序列号开始,即 1000、2000、3000 而不是 1、2、3。我不知道你的用例,但除非你重新排序很多,否则这将最大限度地减少你必须做的序列号的“颠簸”数量。

【讨论】:

    【解决方案2】:

    假设您已经根据Sequence 对列表进行了排序,您可以使用LINQ 的FindIndex 方法找到具有currSeqnewSeq 的元素的索引,然后使用RemoveAtInsert 将更新的元素放置在正确的位置。

    类似这样的:

    int currSeq = 2;
    int newSeq = 5;
    var oldIndex = categories.FindIndex(i => i.Sequence == currSeq);
    var newIndex = categories.FindIndex(i => i.Sequence == newSeq);
    
    if(oldIndex > -1)
    {
        var oldItem = lst[oldIndex];
        oldItem.ID = newSeq;
    
        if(newIndex > -1)
        {
            newIndex = newIndex-1 < 0 ? 0 : newIndex - 1;    //in case the first element is the existing one
            categories.RemoveAt(oldIndex);
            categories.Insert(newIndex, oldItem);
        }
        else
        {
            categories = lst.OrderBy(i => i.ID).ToList();
        }
    }
    

    【讨论】:

      【解决方案3】:

      我认为这将解决您的问题。但是当插入所有以下行时,也会移动。你可以这样吗?

          var categories = new List<Category>() {
              new Category() { sequence = 3, categoryName = "Category F" },
              new Category() { sequence = 1, categoryName = "Category S" },
              new Category() { sequence = 2, categoryName = "Category Z" },
              new Category() { sequence = 4, categoryName = "Category X" },
              new Category() { sequence = 5, categoryName = "Category V" }
          };
      
          List<string> list = new List<string>();
          for (int i = 0; i < 6; i++)
          {
              list.Add("");
          }
      
          foreach (var item in categories)
          {
              list[item.sequence] = item.categoryName;
          }
      
          var removeFrom = 2;
          var removeTo = 5;
      
          list.Insert(removeTo, list[removeFrom]);
          list.RemoveAt(removeFrom);
      

      【讨论】:

        【解决方案4】:

        根据评论和已编辑的 OP 进行更新。

        假设您的 Category 类定义如下。

        public class Category
        {
            public int sequence{get;set;}
            public string categoryName{get;set;}
        }
        

        当newValue

         public static List<Category> UpdateSequence(this List<Category> categories, int oldValue,int newValue)
         {
                var invalidState = -1;
                if(oldValue>newValue)
                {
                    categories.Single(x=>x.sequence == oldValue).sequence = invalidState;
                    if(categories.Any(x=>x.sequence == newValue))
                    {
                        categories = UpdateSequence(categories, newValue,newValue+1);
                    }
                    categories.Single(x=>x.sequence == invalidState).sequence = newValue;
                }
                else
                {
                    if(categories.Any(x=>x.sequence == newValue))
                    {
                        categories = UpdateSequence(categories, newValue,newValue+1);
                    }
                    categories.Single(x=>x.sequence==oldValue).sequence = newValue;
                }
                return categories;
            }
        

        输入

        var categories = new List<Category>() {
            new Category() { sequence = 3, categoryName = "Category F" },
            new Category() { sequence = 1, categoryName = "Category S" },
            new Category() { sequence = 2, categoryName = "Category Z" },
            new Category() { sequence = 5, categoryName = "Category X" },
            new Category() { sequence = 6, categoryName = "Category V" }
        

        场景 1:

        int currSeq = 2;
        int newSeq = 1;
        var result = categories.UpdateSequence(currSeq,newSeq).OrderBy(x=>x.sequence);
        

        输出

        1 Category Z 
        2 Category S 
        3 Category F 
        5 Category X 
        6 Category V 
        

        场景 2

        int currSeq = 3;
        int newSeq = 1;
        var result = categories.UpdateSequence(currSeq,newSeq).OrderBy(x=>x.sequence);
        

        输出

        1 Category F 
        2 Category S 
        3 Category Z 
        5 Category X 
        6 Category V 
        

        【讨论】:

        • 非常感谢,但是当 newValue
        • @joegreentea 我已经更新了你提到的案例的答案。您能否验证这是否是所需的输出。如果没有,您能否在场景中提及所需的输出?
        • 是的,当新序列
        • 我发布的输出基于相同的代码。您能否使用遇到问题的确切情况以及在这种情况下所需的输出来更新 OP
        • @joegreentea 已根据您证明的新示例更新了答案。请验证
        猜你喜欢
        • 2015-09-16
        • 2019-09-18
        • 1970-01-01
        • 1970-01-01
        • 2020-10-29
        • 1970-01-01
        • 2023-02-21
        • 2016-01-26
        • 1970-01-01
        相关资源
        最近更新 更多