使用多个子列表重新排序主列表

时间:2012-03-23 18:54:52

标签: c# arrays list

我正在尝试将较小列表的顺序维持在较大的列表中。假设有三个列表:

List A = { Beef, Ham, Chicken }
List B = { Cat, Monkey, Dog }

List C = { Veal, Ham, Beef, Chicken, Deer, Dog, Cat, Monkey }

列表A和B是C的子集。您可以看到A中的项目在C中是乱序的。我想在C内保持A和B的顺序。因此,C的输出应该是:

{ Veal, Beef, Ham, Chicken, Deer, Cat, Monkey, Dog }

请注意,不在A或B中的物品会保留在C(小牛肉和鹿肉)中的原始位置。而且,A或B中的项目总是在一起。 C的排序必须在创建C之后完成,因为A和B订单可以更改,如果发生这种情况,则必须更新C.

如何实现这一目标?感谢。

2 个答案:

答案 0 :(得分:2)

C不应该是列表,它应该是列表列表

这样,C对于子列表元素从不具有自己的单独的顺序,因此重新排序子列表会自动反映在C中,而无需任何额外操作。到时候,您可以使用SelectMany轻松“压扁”C。

例如:

class Program {

    static void Main(string[] args) {

        var A = new List<string> { "Ham", "Beef", "Chicken" };
        var B = new List<string> { "Cat", "Dog", "Monkey" };
        var C = new List<List<string>> {
            new List<string> { "Veal" },
            A,
            new List<string> { "Deer" },
            B
        };

        Console.WriteLine("ORIGINAL LIST:");
        foreach (var element in C.SelectMany(l => l))
            Console.WriteLine(element);

        // Now reorder one of the sub-lists (swap "Ham" and "Beef"):
        var tmp = A[0];
        A[0] = A[1];
        A[1] = tmp;

        Console.WriteLine("\nREORDERED LIST:");
        foreach (var element in C.SelectMany(l => l))
            Console.WriteLine(element);

    }

}

打印:

ORIGINAL LIST:
Veal
Ham
Beef
Chicken
Deer
Cat
Monkey
Dog

REORDERED LIST:
Veal
Beef
Ham
Chicken
Deer
Cat
Monkey
Dog

这一切都在假设子列表不相交的情况下起作用。如果某个元素在多个子列表之间共享但需要在C中只存在一次,则此模型会中断。但话说回来,你原来的模型也会崩溃,所以我冒昧地假设情况并非如此。

答案 1 :(得分:0)

你可以这样做。

var A = new List<string> { "Beef", "Ham", "Chicken" };
var B = new List<string> { "Cat", "Monkey", "Dog" };
var C = new List<string> { "Veal", "Ham", "Beef", "Chicken", "Deer", "Dog", "Cat", "Monkey" };

// To quickly check if C[i] belongs to the corresponding list.
var sA = new HashSet<string>(A);
var sB = new HashSet<string>(B);
List<string> currentList = null;
int pos = 1;
for (int i = 0; i < C.Count; i++)
{
    string el = C[i];
    if (currentList != null)
    {
        if (pos == currentList.Count)
        {
            pos = 1;
            currentList = null;
        }
        else
        {
            C[i] = currentList[pos];
            pos++;
        }
    }
    else if (sA.Contains(el))
    {
        currentList = A;
        C[i] = currentList[0];
    }
    else if (sB.Contains(el))
    {
        currentList = B;
        C[i] = currentList[0];
    }
}

// Outputs "Veal,Beef,Ham,Chicken,Deer,Cat,Monkey,Dog"
Console.WriteLine(string.Join(",", C));