【问题标题】:Sorting by name after each entry每个条目后按名称排序
【发布时间】:2013-01-22 15:34:26
【问题描述】:

我正在使用此 LINQ 语句按产品名称(升序)对列表进行排序,其中包含每个产品可用的产品名称 (string) 和 Sizes (List<byte>);

LinkedList<FullItemDetails> itemDetails = new LinkedList<FullItemDetails>();  

public class FullItemDetails   
{
    public string ProductName { get; set; }
    public List<byte> Sizes { get; set; }
}

现在每次我输入一个新条目 ex; Jacket,6,12,18,10,我认为我的程序正在重新排序我的列表;

itemDetails.AddLast(fullItemDetails);

//SortedProducts
itemDetails = Products.OrderBy(x => x.ProductName).ToList();

如果列表已经排序,我只需将最后一个条目放在正确的位置。 最好的方法是什么。也可以降低算法的复杂度。谢谢

【问题讨论】:

  • 根据您处理的数据集有多大,每次重新排序是否会影响性能?该方法必须比较产品名称以确定订单,并且您在正确的位置插入也将执行相同的操作。在这种情况下,您将获得 o(N) 的速度。如果数据集不是很大,我不会担心。
  • 您使用的是LinkedList 还是List?您声明了 LinkedList,但 LINQ 返回了 List

标签: c# linq sorting


【解决方案1】:

这对于SortedList 来说似乎是一个理想的问题,因为您有一个键(名称)和值(List&lt;int&gt; 的大小)。

文档可在此处获得:http://msdn.microsoft.com/en-us/library/system.collections.sortedlist.aspx

列表声明如下所示:SortedList&lt;string, List&lt;int&gt; &gt;。所有插入都将按字符串排序,并且可以根据每个键枚举值。

【讨论】:

  • SortedSet 可能更合适。
  • 工作完美,谢谢。我读到 SortedList 使用二进制搜索来搜索键。复杂度为 O(logN)。我认为这对于在正确的位置插入单个条目是相同的。
  • SortedList 插入是 O(N)。正如 jessehouwing 所说,考虑改用 SortedSet
  • 两个都不错,看他需要什么。如果他想要与特定产品名称关联的所有尺寸,SortedList 可能更适合开箱即用的功能。与 Tuple 结合的 SortedSet 也可能符合要求,甚至连接候选值(名称 + 大小)。取决于实现,但赞成注意到 SortedSet :)
  • 而用户...,正如 Timothy Shields 所提到的,插入的大 O 复杂度是 O(n),因为插入的最坏情况是必须调整列表的大小。但是,当插入到容量不足的列表中时,它只有 O(logN),正如您所指出的。
【解决方案2】:

使用SortedList&lt;TKey, TValue&gt;SortedSet&lt;T&gt; 代替List&lt;T&gt;。您可以传入IComparer&lt;T&gt; 以使用特定的排序算法through the respective constructorShould you want to use a Lambda expression, you can use a small wrapper class to wrap a Comparison&lt;T&gt;.

这将导致类似:

ICollection<FullItemDetails> _itemList = new SortedSet<FullItemDetails>(new ComparisonComparer<FullItemDetails>((x,y) -> x.ProductName.CompareTo(y.ProductName))

您的收藏现在将始终被订购。

当您使用 .NET 4.5 时,您可以use Comparer&lt;T&gt;.Create to create an IComparer implementation from a lambda expression

【讨论】:

  • 顺便说一句,不是SortedList&lt;T&gt;,而是SortedList&lt;TKey, TValue&gt;
  • 谢谢,已修复。这就是为什么我还包括了 SortedSet。 SortedList 更像是一个自动字典,而不是一个排序列表。
【解决方案3】:

您可以使用SortedList&lt;string,FullItemDetails&gt;

然后你像这样添加你的时间list.Add(fullItemDetails.Name,fullItemDetails)

[编辑]:添加或删除元素后,顺序将保持不变。

[Edit2] 使用 LINQ 您使用列表来存储您的项目(添加/删除):List&lt;FullItemDetails&gt; originalList 和其他属性以读取您的排序数据:

IEnumerable<FullItemDetails> sortedList = originalList.OrderBy(e => e.Name).ThenBy(e => /* logic to order by another property*/);

现在您可以遍历您的sortedList,因为这个排序列表是一个IEnumerable&lt;T&gt;,每次您遍历它时,您将拥有与originalList 中完全相同的元素(在添加或删除项目之后)。

换句话说:sortedList 仅包含读取您的originalList 的逻辑。

希望这会有所帮助。 问候。

【讨论】:

  • 我正在尝试使用您的方法,但由于每个条目除了名称之外都会有一个尺寸列表,因此我还需要存储它们。我怎样才能实现你的尺寸方法?
  • 在这种情况下,我可以使用 LINQ 提出另一种解决方案(参见我的回答中的 Edit2)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-24
  • 2013-07-21
  • 2018-03-26
相关资源
最近更新 更多