首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C#中有没有等同于F# Seq.windowed的东西?

在C#中有没有等同于F# Seq.windowed的东西?
EN

Stack Overflow用户
提问于 2012-01-16 09:25:22
回答 4查看 2K关注 0票数 7

我正在编写一些C#代码来处理移动平均等问题,在这些代码中,我经常需要获取一个List / IEnumerable并处理连续的数据块。F# Seq模块有一个很棒的函数windowed,它接受一个序列,返回一个由连续元素组成的序列。

C#有没有开箱即用的等效功能?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-01-16 09:40:39

您可以随时从C#调用SeqModule.Windowed,只需引用FSharp.Core.Dll即可。函数名也有些混乱,所以调用Windowed而不是windowed,这样它就符合C#的大写约定

票数 9
EN

Stack Overflow用户

发布于 2012-01-16 17:23:49

你可以随时使用你自己的代码(或者翻译来自F#内核的代码):

代码语言:javascript
复制
let windowed windowSize (source: seq<_>) =    
    checkNonNull "source" source
    if windowSize <= 0 then invalidArg "windowSize" (SR.GetString(SR.inputMustBeNonNegative))
    seq { let arr = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked windowSize 
            let r = ref (windowSize-1)
            let i = ref 0 
            use e = source.GetEnumerator() 
            while e.MoveNext() do 
                arr.[!i] <- e.Current
                i := (!i + 1) % windowSize
                if !r = 0 then 
                    yield Array.init windowSize (fun j -> arr.[(!i+j) % windowSize])
                else 
                r := (!r - 1) }

我的尝试是这样的,它比直接调用F# (由John Palmer建议)要慢得多。我猜这是因为F#使用了未检查的数组。

代码语言:javascript
复制
public static IEnumerable<T[]> Windowed<T>(this IEnumerable<T> list, int windowSize)
{
    //Checks elided
    var arr = new T[windowSize];
    int r = windowSize - 1, i = 0;
    using(var e = list.GetEnumerator())
    {
        while(e.MoveNext())
        {
            arr[i] = e.Current;
            i = (i + 1) % windowSize;
            if(r == 0) 
                yield return ArrayInit<T>(windowSize, j => arr[(i + j) % windowSize]);
            else
                r = r - 1;
        }
    }
}
public static T[] ArrayInit<T>(int size, Func<int, T> func)
{
    var output = new T[size];
    for(var i = 0; i < size; i++) output[i] = func(i);
    return output;
}
票数 2
EN

Stack Overflow用户

发布于 2018-07-10 04:29:57

John Palmer的答案很好,这里有一个基于他的答案的例子。

代码语言:javascript
复制
var numbers = new[] {1, 2, 3, 4, 5}; 
var windowed = SeqModule.Windowed(2, numbers);

您可能想(或者不想)在末尾添加ToArray(),如果没有ToArray,返回类型仍然是序列世界( F# )。有了ToArray,它又回到了C#的世界(数组)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8874901

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档