【问题标题】:How to sort a list compared to an existing list in C#?与 C# 中的现有列表相比,如何对列表进行排序?
【发布时间】:2012-05-01 03:01:44
【问题描述】:

我有一个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-list 中删除了 id=299,以便稍后尝试再次添加它。如何在15515 之间插入它?我知道我可以使用 list.Insert(obj, index) 方法在列表中的任何位置插入,但我如何以最简单的方式以编程方式执行此操作?

【问题讨论】:

  • 您对使用SortedList Class有异议吗?
  • 列表显然不是以...开头的排序
  • @JacekGorgoń 伙计,我不适合阅读问题。 :(
  • 很好的反馈家伙!非常感谢您的帮助!

标签: c# linq list sorting


【解决方案1】:

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

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

这将根据原始完整列表中每个 ID 的索引对所选 ID 列表进行排序。

【讨论】:

  • 经过广泛的测试,这在 10 个案例中有 9 个有效。但是,一些项目仍被添加到列表顶部,没有应用任何类型的排序。
  • @KrisSelbekk:如果你能重现它,你应该问一个新问题,这对其他人来说可能也很有趣。你能举个例子吗?你确定原因不是LINQ's deferred-execution?您可以在最后调用ToList() 轻松绕过。
【解决方案2】:

在伪代码中:

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

如果此索引为 0,则将您的元素添加到列表的开头。

其他索引 = x;

取index = x - 1的元素;

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

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

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

【讨论】:

    【解决方案3】:

    如果你使用SortedDictionary 而不是列表呢?键是索引,值是 ID。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        Tim 的答案非常紧凑和酷,但复杂性非常令人讨厌。以下内容在更大的列表上应该更快,更有用,虽然不是那么紧凑。

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

        更复杂,但计算复杂度更高。

        【讨论】:

          【解决方案6】:

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

          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 的数字顺序进行排序。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-02-18
            • 2016-11-03
            • 1970-01-01
            • 2013-02-13
            • 1970-01-01
            • 1970-01-01
            • 2018-07-01
            • 2010-11-18
            相关资源
            最近更新 更多