简体   繁体   English

在c#中进行序列更新后重新排列通用列表

[英]Rearrange generic list after sequence update in c#

Let's say I have a generic List such as this: 假设我有一个通用列表,例如:

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" }
};

I'm trying to replace the given sequence number with another ie update item in the list with sequence# 2 with number 5 as below: 我正在尝试用另一个替换给定的序列号,即列表中的更新项目,序号为#2,编号为5,如下所示:

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

If the newSeq were not become duplicate eg newSeq = 6, I could just do OrderBy: 如果newSeq没有变成重复,例如newSeq = 6,我可以做OrderBy:

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

But the problem is when they become duplicates, I need the newSeq become in sequence# 5 and bump the other duplicated sequence# 5 + 1. 但问题是当它们变成重复时,我需要newSeq成为序列#5并撞击其他重复序列#5 + 1。

Please help with any guidance solving this. 请帮助解决这个问题的任何指导。 Thanks. 谢谢。

Update: certain cases when new sequence < old sequence, the output is not as desired. 更新:某些情况下新序列<旧序列,输出不符合要求。

Scenario A: 情景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);

Output Scenario A: 输出方案A:

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

Desired Output Scenario A: 期望的输出情景A:

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

Scenario B: 情景B:

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

Output Scenario B: 输出方案B:

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

Desired Output Scenario B: 期望的输出情景B:

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

Do what elgonzo said in his comment. 做elgonzo在评论中说的话。 Plus start out with widely spaced sequence numbers, ie 1000, 2000, 3000 rather than 1,2,3. 另外,从宽间隔的序列号开始,即1000,2000,3000而不是1,2,3。 I don't know your use case, but unless you are reordering a lot, this will minimize the number of "bumps" of sequence numbers you have to do. 我不知道你的用例,但除非你重新排序,否则这将减少你必须做的序列号的“颠簸”次数。

Assuming that you have sorted the list based on the Sequence already, you can use the FindIndex method of LINQ to find the index of element with currSeq and newSeq and then use RemoveAt along with Insert to place the updated element at correct position. 假设您已经基于Sequence对列表进行了Sequence ,可以使用LINQ的FindIndex方法通过currSeqnewSeq查找元素的索引,然后使用RemoveAtInsert将更新的元素放在正确的位置。

Something like this: 像这样的东西:

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();
    }
}

I think this will solve your issue. 我认为这将解决您的问题。 But when inserting all following lines are moved too. 但是当插入所有后续行时也会移动。 Is this okay for you? 这对你好吗?

    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);

Update based on comment and Edited OP. 根据评论更新并编辑OP。

Assuming your Category class is defined as following. 假设您的Category类定义如下。

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

You can write the Update Sequence method as follows to get the desired result when newValue < oldValue. 您可以按如下方式编写Update Sequence方法,以便在newValue <oldValue时获得所需的结果。

 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;
    }

Input 输入

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" }

Scenario 1: 场景1:

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

Output 产量

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

Scenario 2 情景2

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

Ouput 输出继电器

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM