Создайте счетчик<{тип данных, datatype}> из 2-х перечислимых?

StackOverflow https://stackoverflow.com/questions/1616554

  •  06-07-2019
  •  | 
  •  

Вопрос

привет.

Это то, что я хочу сделать:

    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);
    }

Чего я хочу:

9 | 1
1 | 9

Что я действительно понимаю:

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

Этот код является чистым примером.Он может выполнять итерации по массивам или какой-либо другой коллекции.Он также будет выполнять некоторые другие действия, но они не имеют отношения к данной проблеме.

Без linq я мог бы сделать что-то вроде этого:

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

Но вместо этого мне нужен запрос, который может делать все, что мне нужно.

Действительно ли мне нужно создавать свой собственный метод enumerator, который использует yield для создания того, что я хочу?

Редактировать:по запросу:Пример того, что я хотел бы уметь делать:

    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' });

Я бы хотел повернуть вспять и т.д.в самом запросе.Поэтому я храню все это в собранном виде.Дополнительный:Будучи в состоянии выполнить это с помощью sql-подобного приукрашенного синтаксиса, я был бы в восторге.То есть вместо цепочки методов.

Это было полезно?

Решение

Вы можете использовать:

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

Редактировать:

Учитывая ваш новый вопрос, вы сможете сделать:

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

Другие советы

Мой другой ответ менее полезен, чем мог бы быть, потому что функция Enumerable.Zip была добавлена в версии 4.

Итак, вот как сделать свой собственный:

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);
            }
        }
    }
}

Использовать Перечисляемый.Zip.Ваш первый пример можно переписать так:

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);
}

к

str2 = "91";
str1 = "19";
var strings = Enumerable.Zip(c1, c2, (a, b) => a + " | " + b);
foreach (var str in strings)
{
    Console.WriteLine(str);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top