【问题标题】:Using Linq Aggregate to return array of values使用 Linq 聚合返回值数组
【发布时间】:2011-04-15 02:10:21
【问题描述】:

我有这样的事情:

long[] f = new long[4]{1,10,100,1000};

我想将 1000 除以 100、100 除以 10 和 10 除以 1

有没有办法在一个数组中返回结果,例如/10,10,10

更新:这似乎使一些人感到困惑,所以这里是另一个例子

long[] f = new long[3]{1,2,6};

我想将 6 除以 2 和 2 除以 1 并将结果放在一个数组中

【问题讨论】:

  • 问题陈述对我来说不清楚。你想把每个元素除以对应的十次方吗? (10^i)。除以前一个元素?在那种情况下,你想在零除法的情况下发生什么?

标签: c# .net linq .net-3.5 c#-3.0


【解决方案1】:

我不认为聚合在这种情况下会有帮助...... Zip 会更适合:

long[] f = new long[4]{1,10,100,1000};
long[] result = f.Skip(1).Zip(f, (a, b) => a / b);

编辑:如果您使用的是 .NET 3.5,您可以自己轻松编写 Zip 扩展方法:

    public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> selector)
    {

        if (first == null)
            throw new ArgumentNullException("first");
        if (second == null)
            throw new ArgumentNullException("second");
        if (selector == null)
            throw new ArgumentNullException("selector");

        return first.ZipIterator(second, selector);
    }

    private static IEnumerable<TResult> ZipIterator<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> selector)
    {
        using (var enum1 = first.GetEnumerator())
        using (var enum2 = second.GetEnumerator())
        {
            while (enum1.MoveNext() && enum2.MoveNext())
            {
                yield return selector(enum1.Current, enum2.Current);
            }
        }
    }

【讨论】:

    【解决方案2】:

    如果我理解正确,您可能不想在这里使用 Aggregate 而是 Pairwise:

    long[] result = f.Pairwise((x, y) => y / x).ToArray();
    

    下面是 Pairwise 的一个示例实现:

    public static IEnumerable<TResult> Pairwise<TSource, TResult>(
        this IEnumerable<TSource> source,
        Func<TSource, TSource, TResult> resultSelector)
    {
        TSource previous = default(TSource);
    
        using (var it = source.GetEnumerator())
        {
            if (it.MoveNext())
                previous = it.Current;
    
            while (it.MoveNext())
                yield return resultSelector(previous, previous = it.Current);
        }
    }
    

    Source

    如果您希望以相反的顺序获得结果,请添加对 Reverse 的调用。

    【讨论】:

      【解决方案3】:

      不使用 Linq 的简单解决方案:

          IEnumerable<long> GetResults(long[] input)
          {
              for (int i = input.Length -1; i >= 1; --i)
                  yield return input[i] / input[i - 1];
          }
      

      您可以在返回值上使用 Linq,它适用于 .NET 3.5 :)

      【讨论】:

      • 虽然这个实现可以工作,但它要求输入是直接可访问的。首选通用的“IEnumerable”解决方案。
      • 好吧,我的解决方案解决了问题,而且非常紧凑。我不明白为什么有人会减去一个可行的解决方案——这太荒谬了。如果他们知道的话,任何人都可以提供更好的选择。
      • @xtofl:参数类型可以更改为 ReadOnlyCollection。但是testalino的解决方法还是file。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-25
      相关资源
      最近更新 更多