如何将列表与C#中的现有列表进行排序?

时间:2012-04-19 14:53:06

标签: c# linq list sorting

我有一个List<int> allIDs,其中包含原始订单中的ID列表。我正在创建一个元素选择器,它允许用户在此列表中添加和删除ID到另一个List<int> selectedIDs。现在,我已经全力以赴,但是每当用户删除并稍后添加相同的元素时,它就会被添加到列表的末尾(selectedIDs.Add( id ))。

我希望将元素插入其原始位置,使用allIDs作为对以前位置的引用。

以下是将所有内容放在上下文中的一些摘录:

List<int> allIDs = new List<int> {10, 11, 9, 155, 12, 299, 15...};
List<int> selectedIDs = new List<int> { 10, 9, 155, 299, 15... }

现在假设我从selectedIDs列表中删除了id = 299,以便稍后尝试再次添加。如何在15515之间插入?我知道我可以使用list.Insert(obj, index)方法在列表中的任何位置插入,但是如何以最简单的方式以编程方式执行此操作?

6 个答案:

答案 0 :(得分:6)

如果我已正确理解您的要求:

var ordered = selectedIDs.OrderBy(sID => allIDs.IndexOf(sID));

这将按原始完整列表中每个id的索引排序所选ID的列表。

答案 1 :(得分:1)

在伪代码中:

在第一个列表中查找元素的索引。

如果此索引为0,请在列表的开头添加元素。

Else index = x;

获取index = x - 1;

的元素

如果索引为x - 1的元素在您的列表中,请在之后添加新元素。

否则,如果x - 2> = 0,则使用索引x - 2处的元素再次循环。

在列表中已经包含该元素的索引之前,您最终将获得该元素的索引,并且您将在此索引处插入新元素+。

答案 2 :(得分:1)

如果使用SortedDictionary而不是列表,怎么样?键是索引,值是ID。

答案 3 :(得分:1)

一种选择是拥有List<MyClass>而不是List<int>。 MyClass有两个属性,intbool shouldDisplay。您可以将其标记为隐藏或不显示,而不是从第一个列表中删除项目。要取消删除它们,只需将它们设置为“可见”。

答案 4 :(得分:1)

蒂姆的回答非常紧凑而且很酷,但却有着非常讨厌的复杂性。以下内容应该更快,更适用于较大的列表,尽管不是那么紧凑。

public class IdWithFlag
{
     public int Id { get; set; }
     public bool Selected { get; set; }
}

Dictionary<int, IdWithFlag> allIDs = ... // populate somehow, perhaps a custom cast operator would help

现在,每次添加/删除所选ID时,都会重新生成另一个列表:

allIDs[currentlyChangedId].Selected = ... // added or removed?

List<int> selectedIDs = allIDs.Values
    .Where(id => id.Selected)
    .Select(id => id.Id)
    .ToList();

更复杂,但具有更好的计算复杂性。

答案 5 :(得分:1)

这不是最有效的答案,但我认为这是最容易编码的答案:

List<int> allIDs = new List<int> { 10, 11, 9, 155, 12, 299, 15 };
List<int> selectedIDs = new List<int> { 299, 10, 9, 15, 11 };

// this will ensure the sort order...
var newSel = (from a in allIDs
    join s in selectedIDs on a equals s
    select a).ToList();

selectedIDs = newSel;

结果输出将始终按照allIDs数字顺序排序。