迭代并返回连续 n 个元素的数组

发布于 2024-10-11 10:59:35 字数 596 浏览 5 评论 0 原文

在 Ruby 中,Enumerable 上有一个 each_cons一个>。它的工作原理是这样的

(1..5).each_cons(3) {|n| p n}

[1,2,3]
[2,3,4]
[3,4,5]

我想用 C# 来做这件事。 LINQ 会很好。

下面的代码做了类似的事情,但它循环一对多,并且还被硬编码为仅返回两个元素

var ints = new int[] { 1, 2, 3, 4, 5, 6, 7 };
var cons = ints.Select((o, i) =>
            new int[]{ ints[i], i == ints.Length - 1 ? 0 : ints[i + 1] });

。如果可以将其创建为原始数组的迭代器,而不必创建大量数组,那就太好了。

In Ruby there is an each_cons on Enumerable. It works like this

(1..5).each_cons(3) {|n| p n}

[1, 2, 3]
[2, 3, 4]
[3, 4, 5]

I would like to do this in C#. LINQ would be nice.

The following does something similar but it loops one to many and it's also hardcoded to return only two elements

var ints = new int[] { 1, 2, 3, 4, 5, 6, 7 };
var cons = ints.Select((o, i) =>
            new int[]{ ints[i], i == ints.Length - 1 ? 0 : ints[i + 1] });

It would be nice if it could be created as an iterator over the original array instead of having to create a lot of arrays.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无名指的心愿 2024-10-18 10:59:35

尝试以下操作

var ints = Enumerable.Range(1, 3).Select(x => Enumerable.Range(x, 3));

这将返回具有指定值的 IEnumerable> 。如果这是意图的话,您可以随时添加 .ToArray 表达式以将其放入数组中(无法判断这是否是 ruby​​ 中 [] 的含义)

Try the following

var ints = Enumerable.Range(1, 3).Select(x => Enumerable.Range(x, 3));

This will return an IEnumerable<IEnumerable<int>> with the specified values. You can add the .ToArray expression at any point to get it into an array if that's the intent (can't tell if that's whatthe [] mean in ruby)

吻安 2024-10-18 10:59:35

您可以创建一个扩展方法,以这种方式实现它:

    public static IEnumerable<IEnumerable<T>> each_cons<T>(this IEnumerable<T> enumerable, int length)
    {
        for (int i = 0; i < enumerable.Count() - length + 1; i++)
        {
            yield return enumerable.Skip(i).Take(length);
        }
    }

使用它:

var ints = Enumerable.Range(1, 7).each_cons(3);

You can create an extension method that achieves it in this way:

    public static IEnumerable<IEnumerable<T>> each_cons<T>(this IEnumerable<T> enumerable, int length)
    {
        for (int i = 0; i < enumerable.Count() - length + 1; i++)
        {
            yield return enumerable.Skip(i).Take(length);
        }
    }

Consume it:

var ints = Enumerable.Range(1, 7).each_cons(3);
彡翼 2024-10-18 10:59:35

这是一个通用的扩展方法,对于我当前的用例来说,它有点复杂,但它似乎有效。

static class EnumerableExtension
{
    public static IEnumerable<IEnumerable<T>> EachCons<T>(this IEnumerable<T> sequence, int cons)
    {
        for (IEnumerable<T> head = sequence.Take(cons), tail = sequence.Skip(1);
             head.Count() == cons; head = tail.Take(cons), tail = tail.Skip(1))
             yield return head;
    }
}

改用 Jay 的实现。速度快得多。我刚刚把这个留在这里,因为杰伊的回答中提到了它。

Here's a generic extension method that turned out to be way to complicated for my current use case but it seems to work.

static class EnumerableExtension
{
    public static IEnumerable<IEnumerable<T>> EachCons<T>(this IEnumerable<T> sequence, int cons)
    {
        for (IEnumerable<T> head = sequence.Take(cons), tail = sequence.Skip(1);
             head.Count() == cons; head = tail.Take(cons), tail = tail.Skip(1))
             yield return head;
    }
}

Use Jay's implementation instead. It's MUCH faster. I just left this one here because it's mentioned in Jay's answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文