【问题标题】:sort a dictionary <object, List<int>> c#排序字典<object,List<int>> c#
【发布时间】:2015-01-14 22:13:58
【问题描述】:

我想对一个对象列表进行排序,结构是Dictionary&lt;Object, List&lt;int&gt;&gt;

字典中的项目将是

item_1, (2,2,3)
item_2, (1,3,4)
item_3, (2,3,4)
item_4, (1,2)

一旦项目被排序,它们应该显示为

item_4, 1,2
item_2, 1,3,4
item_1, 2,2,3
item_3, 2,3,4

所以,基本上我必须对列表中的第一项进行排序,然后是第二项,然后是第三项,使用 linq 实现这种解决方案的简单方法是什么

【问题讨论】:

  • 您的字典中value 中的项目是否需要订购,或者您必须在订购钥匙的同时订购它们?此外,您是希望字典不断订购还是在需要不时打印出来时按需订购。如果你想不断地排序,你的字典会更慢,你需要使用OrderedDictionary
  • 值中的项目首先需要订购,需要按需订购
  • 项目的排序是否应该影响存储的List&lt;int&gt;?另外,如果我有 item_5, (1,2,3) 哪个项目先出现,Item_4 还是 Item_5?最后,你能保证List&lt;int&gt; 中的项目是预先排序的吗?如果可以的话,它会使问题变得容易得多。
  • List 只是为了方便——本质上,视图模型被传递给视图,并且在控制器中进行排序

标签: c# sorting dictionary


【解决方案1】:

您需要的是一个自定义比较器,它可以基于该序列中的项目来比较一系列值,而不是基于对序列本身的引用(假设大多数序列不会覆盖默认的相等行为)。这很简单:

public class SequenceComparer<T> : IComparer<IEnumerable<T>>
{
    private IComparer<T> comparer;
    public SequenceComparer(IComparer<T> comparer = null)
    {
        this.comparer = comparer ?? Comparer<T>.Default;
    }

    public int Compare(IEnumerable<T> x, IEnumerable<T> y)
    {
        using (var first = x.GetEnumerator())
        using (var second = y.GetEnumerator())
        {
            while (true)
            {
                var hasFirst = first.MoveNext();
                var hasSecond = second.MoveNext();
                if (hasFirst && !hasSecond)
                    return 1;
                if (hasSecond && !hasFirst)
                    return -1;
                if (!hasFirst && !hasSecond)
                    return 0;
                var comparison = comparer.Compare(first.Current, second.Current);
                if (comparison != 0)
                    return comparison;
            }
        }
    }
}

然后您可以使用此比较器订购您收藏中的物品:

var query = dictionary.OrderBy(pair => pair.Value, new SequenceComparer<int>());

如果您希望序列中的项目根据它们的排序值排序,并且序列尚未排序,那么您可以在查询中添加内部序列的排序:

var query = dictionary.OrderBy(pair => pair.Value.OrderBy(x => x), 
    new SequenceComparer<int>());

【讨论】:

  • 你在调用什么 OrderBy 调用,接收 IEqualityComparer&lt;T&gt;
  • @ScottChamberlain 对,对不起,抓错了来源。
【解决方案2】:

您可以使用自定义比较方法对单独列表中的字典值进行排序:

  static void Main()
  {
        var map = new Dictionary<object, IList<int>>();

        map.Add("item_1", new int[] { 2, 2, 4 });
        map.Add("item_2", new int[] { 1, 3, 4 });
        map.Add("item_3", new int[] { 2, 3, 4 });
        map.Add("item_4", new int[] { 1, 2});

        var list = new List<KeyValuePair<object, IList<int>>>(map);

        list.Sort(CompareSequences);


        foreach(var item in list)
        {
            Console.WriteLine("{0} ({1})", item.Key, string.Join<int>("," , item.Value));
        }

  }



    static int CompareSequences(KeyValuePair<object, IList<int>> left, 
        KeyValuePair<object, IList<int>> right)
    {
         int count = Math.Min(left.Value.Count, right.Value.Count);

        for (int i = 0; i < count; ++i)
        {
            if (left.Value[i] < right.Value[i])
            {
                return -1;
            }

            if (left.Value[i] > right.Value[i])
            {
                return 1;
            }
        }

        if (right.Value.Count > count)
        {
            return -1;
        }

        if (left.Value.Count  > count)
        {
            return 1;
        }

        return 0;
    }

与 OrderBy() 排序的一个区别是 List.Sort() 中的排序算法不稳定。 但它使用更少的内存和更少的临时对象

【讨论】:

  • 有效,但没有按照 OP 的要求使用 Linq(PS:这是它的 .net fiddle :))。
  • 不错,我没有注意到问题中的Ling,谢谢指点。
猜你喜欢
  • 2021-02-12
  • 1970-01-01
  • 2021-03-08
  • 1970-01-01
  • 1970-01-01
  • 2016-08-01
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多