如何在不更改其类型的情况下订购IGrouping? [英] How to order IGrouping without changing its type?

查看:315
本文介绍了如何在不更改其类型的情况下订购IGrouping?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个IGrouping类型的对象,想在不更改对象类型的情况下对组内的元素进行排序.
换句话说,我有

I have an oject of the type IGrouping and would like to order the elements inside the group without changing the type of the object.
In other words, I have

var tmp = group.OrderBy(x => x);

group的类型为IGrouping<int, someanonymousclass>,我也希望tmp的类型也为IGrouping<int, someanonymousclass>.

with group being of type IGrouping<int, someanonymousclass> and I want tmp to be of type IGrouping<int, someanonymousclass> as well.

一种解决方法是将其更改为Dictionary或新的匿名类,但我希望tmp具体为IGrouping<int, someanonymousclass>类型.

One workaround would be to change it to a Dictionary or a new anonymous class, but I want tmp to specificly be of type IGrouping<int, someanonymousclass>.

换句话说:我想对IGrouping<int, someanonymousclass>对象的元素进行排序.如果使用OrderBy,它将group的类型更改为IOrderedEnumerable,并且我无法再访问group.Key.我如何维持group的类型?

In other words: I want to sort the elemnts of my IGrouping<int, someanonymousclass> object. If I use OrderBy it changes the type of group to IOrderedEnumerable and I cannot access group.Key anymore. How can i sustain the type of group?

示例:

var states = SimulationPanel.innerPanel.Children.OfType<StateBar>().Where(x => x.isSensorState())
                .GroupBy(x => (SensorElement)x.BauplanElement,
                         x => new
                         {
                             Start = (decimal)(x.Margin.Left / SimulationPanel.Zoom),
                             Width = (decimal)(x.Width / SimulationPanel.Zoom),
                             State = x.State
                         });

var group = states.First();
var tmp = group.OrderBy(x => x.Start);
var key = tmp.Key;    //This does not work, because tmp is not of type IGrouping

我知道我可以在分组之前使用OrderBy.不过,我不想这么做.

I know I could use OrderBy before grouping. I don't want to do that, though.

推荐答案

如果您可以,只需将订购提前,例如

If you can, just put the ordering earlier, e.g.

var states = SimulationPanel.innerPanel
       .Children
       .OfType<StateBar>()
       .Where(x => x.isSensorState())
       .OrderBy(x => (decimal)(x.Margin.Left / SimulationPanel.Zoom))
       .GroupBy(...);

(或在OrderBy之前放置Select并简化GroupBy.)

(Or put a Select before the OrderBy and make the GroupBy simpler.)

但是,如果确实需要此功能,则可以编写自己的IGrouping<TKey, TElement>实现和扩展方法来对元素进行排序并将其保留在列表中:

If you really need this though, you could write your own IGrouping<TKey, TElement> implementation and an extension method to order the elements and retain them in a list:

public static class GroupExtensions
{
    public IGrouping<TKey, TElement, TOrderKey> OrderBy
        (this IGrouping<TKey, TElement> grouping,
         Func<TElement, TOrderKey> orderKeySelector)
    {
        return new GroupingImpl<TKey, TElement>
            (grouping.Key, grouping.OrderBy(orderKeySelector));
    }

    private class GroupingImpl<TKey, TElement> : IGrouping<TKey, TElement>
    {
        private readonly TKey key;
        private readonly List<TElement> elements;

        internal GroupingImpl(TKey key, IEnumerable<TElement> elements)
        {
            this.key = key;
            this.elements = elements.ToList();
        }

        public TKey Key { get { return key; } }

        public IEnumerator<TElement> GetEnumerator()
        {
            return elements.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}

这篇关于如何在不更改其类型的情况下订购IGrouping?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆