【问题标题】:LINQ- Combine Multiple List<T> and order by a value (.Net 3.5)LINQ- 组合多个 List<T> 并按值排序(.Net 3.5)
【发布时间】:2008-12-28 20:13:32
【问题描述】:

我正在尝试组合多个List&lt;T&gt; where T:IGetTime(即T 将始终具有方法getTime())。

然后我尝试通过getTime() 返回的DateTime 订购商品。

我的 LINQ 如下所示:

public static List<T> Combine(List<T> one, List<T> two, List<T> three)
    {
        var result = from IGetTime item in one
                     from IGetTime item2 in two
                     from IGetTime item3 in three
                     select new{ item, item2, item3 };

        return result.ToList();
    }

我还没有添加orderby。应该是这样的:

var thestream = from T item in this
                orderby item.getTime() descending
                select item;

到底有没有组合和排序最终列表????

提前致谢,

罗伯托

【问题讨论】:

    标签: c# .net linq generics


    【解决方案1】:

    这里有三个列表 - 究竟你想按什么来订购?

    您的演员表也不正确 - 结果将是一个 IEnumerable&lt;X&gt;,其中 X 是一个匿名类型,其中包含三个 Ts。

    如果这个想法真的是连接三个列表然后排序,你想要:

    return one.Concat(two)
              .Concat(three)
              .OrderByDescending(x => x.GetTime())
              .ToList();
    

    【讨论】:

    • C# 是否知道 x 将有一个 GetTime 方法(或将其转换为 IGetTime)仅仅是因为 where T: IGetTime?如果不是,则 Lambda 需要调整为 x => ((IGetTime)x).GetTime()
    • C~ 确实知道。 T 在 clas decleration 中明确声明: public class TimeStream : List where T : IGetTime
    • 哇,不用演员也能工作,不禁动摇这种感觉,这让 C# magix pixie dust 走得太远了。
    • @Roberto:仍然有魔法发生,它默默地将 x 转换为 IGetTime,即使 T 的类型是别的东西。它通过检查限制列表中的每个接口来寻找匹配的 GetTime() 签名来做到这一点。
    • @AnthonyWJones:泛型的大部分好处是用编译时类型检查替换运行时强制转换。类型都在那里,由程序员指定。编译器不必费力地检查这些实例是否具有该方法。
    【解决方案2】:

    我会这样做:

    public static List<T> Combine<T, TKey>
    (
      Func<T, TKey> orderingFunction,
      params IEnumerable<T>[] theParams
    )
      where TKey : IComparable
    {
      return theParams
        .SelectMany(x => x)
        .OrderBy(orderingFunction)
        .ToList();
    }
    

    这是一些测试代码:

        public static void Test1()
        {
            List<int> a = new List<int>() { 1, 2, 3 };
            List<int> b = new List<int>() { 3, 2, 1 };
            List<int> c = CombineLists.Combine(i => i, a, b);
            c.ForEach(i => Console.WriteLine(i));
        }
    

    故事是这样的:

    public static List<T> Combine<T, TKey>
    (
      Func<T, TKey> orderingFunction,
      params IEnumerable<T>[] theParams
    )
      where TKey : IComparable
    

    这个签名声明了一个方法,它接受两个类型参数、一些排序函数和一堆集合。请注意,类型 T 和 TKey 没有在测试调用中明确指定。编译器有一个小难题来弄清楚这些类型是什么。首先,它检查给定的 IEnumerable(a 和 b)并发现它们是 int 的 IEnumerable。啊哈,T 必须是整数。然后它检查排序函数并查看它返回的类型与传递的相同。啊哈,TKey 必须是 int。

    where 有点好笑。 OrderBy 应该(在编译时)检查 TKey 是否为 IComparable。它只在运行时检查,因此我们可以在代码中进行编译时检查。

    params 接受任意数量的参数,并引用它们来创建数组。谁愿意被限制在三个列表中?

            return theParams
                .SelectMany(x => x)
                .OrderBy(orderingFunction)
                .ToList();
    

    SelectMany 解压缩集合的集合。这是一种扁平化层次结构的方法。 OrderBy 采用一些函数,将每个元素投影到一个可排序的值,并根据这些值对元素进行排序。 ToList 枚举查询并返回列表。没有惊喜。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-10
      • 2011-06-20
      • 2021-05-25
      • 1970-01-01
      • 2011-02-13
      • 1970-01-01
      • 2021-11-22
      相关资源
      最近更新 更多