Перегруппировать общий список после обновления последовательности в c # - PullRequest
0 голосов
/ 08 июня 2019

Допустим, у меня есть общий список, такой как этот:

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.

Пожалуйста, помогите с любым руководством, решающим это.Спасибо.

Обновление: в некоторых случаях, когда новая последовательность <старая последовательность, выходные данные не соответствуют желаемым. </p>

Сценарий 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

Ответы [ 4 ]

0 голосов
/ 08 июня 2019

Обновление на основе комментария и отредактированного ОП.

Предполагается, что класс вашей категории определен следующим образом.

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

Вы можете написать метод Update Sequence следующим образом, чтобы получить желаемый результат, когда 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;
    }

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

Сценарий 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);

Ouput

1 Category F 
2 Category S 
3 Category Z 
5 Category X 
6 Category V 
0 голосов
/ 08 июня 2019

Предполагая, что вы уже отсортировали список на основе Sequence, вы можете использовать метод LINQ FindIndex, чтобы найти индекс элемента с currSeq и newSeq, а затем использовать RemoveAt вместе с Insert для размещения обновленного элемента в правильном положении.

Примерно так:

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();
    }
}
0 голосов
/ 08 июня 2019

Я думаю, что это решит вашу проблему. Но при вставке все следующие строки тоже перемещаются. Это нормально для тебя?

    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);
0 голосов
/ 08 июня 2019

Делайте то, что сказал elgonzo в своем комментарии. Плюс начните с широко разнесенных порядковых номеров, то есть 1000, 2000, 3000, а не 1,2,3. Я не знаю ваш вариант использования, но если вы не много переупорядочиваете, это сведет к минимуму количество «выпуклостей» порядковых номеров, которые вы должны сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...