简体   繁体   English

从2个可枚举对象创建一个枚举器<{datatype,datatype}>?

[英]Create an enumerator<{datatype, datatype}> from 2 enumerables?

HI.

This is what I want to do: 这就是我想做的:

    str2 = "91";
    str1 = "19";
    var testQuery = from c1 in str1
                    from c2 in str2
                    select new {c1, c2};
    foreach (var enumerable in testQuery)
    {
        Console.WriteLine(enumerable.c1 + " | " + enumerable.c2);
    }

What I want: 我想要的是:

9 | 1
1 | 9

What I really get: 我真正得到的是:

1 | 9
1 | 1
9 | 9
9 | 1

The code is a pure example. 该代码是一个纯示例。 It might iterate through arrays or some other collection. 它可能会遍历数组或其他一些集合。 It will also do some other things, but they are irrelevant to this problem. 它还会做其他一些事情,但是它们与这个问题无关。

Without linq, I could do something like this: 没有linq,我可以做这样的事情:

    for (int i = 0; i < str1.Length -1; i++)
    {
        Console.WriteLine(str1[i] + " | " + str2[i]);
    }

But I want a query that can do everything I need instead. 但是我想要一个查询,它可以代替我做的所有事情。

Do I really have to create my own enumerator method that uses yield to create what I want? 我是否真的必须创建自己的枚举方法,该方法使用yield来创建所需的内容?

EDIT: per request: An example of what I'd like to be able to do: 编辑:每个请求:我想做的一个例子:

    str1 = "91";
    str2 = "19";

    char[] digitX = str1.ToString().Reverse().ToArray();
    char[] digitY = str2.ToString().Reverse().ToArray();

    var q = digitX.Select((c1, i) => new {c1 = c1 - '0', c2 = digitY[i] - '0' });

I'd like to pull the reverse etc. in the actual query. 我想在实际查询中使用相反的方法。 So I keep it all gathered. 所以我把所有的都收集起来。 Extra: Being able to pull this with the sql-like sugarcoated syntax, I'd be thrilled. 补充:能够使用类似sql的Sugarcoated语法来实现这一点,我会很高兴。 Instead of a method chain, that is. 而不是方法链。

My other answer is less useful than it could be, because the Enumerable.Zip function was added in version 4. 我的其他答案没有那么有用,因为在版本4中添加了Enumerable.Zip函数。

So, here's how to roll your own: 所以,这是滚动自己的方法:

public static class EnumerableExtensions
{
    public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(
                                           IEnumerable<TFirst> first,
                                           IEnumerable<TSecond> second,
                                           Func<TFirst, TSecond, TResult> resultSelector)
    {
        using(var firstEnum = first.GetEnumerator())
        using(var secondEnum = second.GetEnumerator())
        {
            while(firstEnum.MoveNext() && secondEnum.MoveNext())
            {
                yield return resultSelector(firstEnum.Current, secondEnum.Current);
            }
        }
    }
}

Use Enumerable.Zip . 使用Enumerable.Zip Your first example can be rewritten from: 您的第一个示例可以重写为:

str2 = "91";
str1 = "19";
var testQuery = from c1 in str1
                from c2 in str2
                select new {c1, c2};
foreach (var enumerable in testQuery)
{
    Console.WriteLine(enumerable.c1 + " | " + enumerable.c2);
}

to

str2 = "91";
str1 = "19";
var strings = Enumerable.Zip(c1, c2, (a, b) => a + " | " + b);
foreach (var str in strings)
{
    Console.WriteLine(str);
}

You can use: 您可以使用:

var testQuery = str1.Select( (c,i) => new {c, str2[i]} );

Edit: 编辑:

Given your new question, you should be able to do: 鉴于您的新问题,您应该可以:

var q = str1.Reverse().Select((c1, i) => new { c1 = c1 - '0', c2 = str2[str2.Length - i - 1] - '0' });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM