Извлечение метода из запроса Linq - PullRequest
0 голосов
/ 21 октября 2019

У меня есть следующий статический метод, который возвращает все возможные комбинации троек из IEnumerable<int>, которые являются пифагорейскими. Например: для int[] array = {1, 2, 3, 4, 5} он вернет new[]{{3, 4, 5}, {4, 3, 5}}.

 public static IEnumerable<IEnumerable<int>> GetPythagoreanNumbers(IEnumerable<int> array)
    {
        return array.SelectMany((a, i) =>
        {
            var inner = array.Skip(i + 1);
            return inner.SelectMany((b, j) =>
                inner.Skip(j + 1)
                    .SelectMany(c => GetTriplePermutations(a, b, c)));
        });
    }

Теперь GetTriplePermutations() возвращает IEnumerable<IEnumerable<int>>, представляющий коллекцию массивов, построенных из 3 целых чисел (a, b,в) получил. По сути, запрос возвращает все возможные расположения 3 элементов из массива, начиная слева направо. (например: {1, 2, 3, 4, 5} => new[]{ {1, 2, 3}, {1, 2, 4}, {1, 2, 5}, {2, 3, 4}, {2, 3, 5}, {3, 4, 5} }). Из всех троек, возвращаемых запросом, GetTriplePermutations() выбирает только те, которые удовлетворяют моему условию.

Мне удалось заставить его работать правильно, однако, когда я выполнял рефакторинг, я заметил, что мой запроссвоего рода повторяется, что означает, что он применяет один и тот же шаблон последовательных методов ext:

array.SelectMany((a, i)).Skip(x + 1).SelectMany((b, j)).Skip(y + 1)

Итак, чтобы исключить повторения, я пытался каким-то образом извлечь метод, который позволил бы кодуконвертируется во что-то вроде этого:

return OddMethod(array).SelectMany(c => GetTriplePermutations(a, b, c)));

Теперь я понятия не имею, как это сделать, так как часть моего кода возвращается запросом Linq. Я думал, что подпись этого «OddMethod» должна выглядеть так:

IEnumerable<IEnumerable<int>> OddMethod(int[] array)

, но не может прогрессировать дальше. Любые идеи, как я мог бы достичь этого "метода извлечения"? Спасибо! :)

Ответы [ 2 ]

0 голосов
/ 22 октября 2019

После некоторой помощи мне удалось найти то, что я искал:

 public static IEnumerable<IEnumerable<int>> GetPythagoreanNumbers(IEnumerable<int> array)
        {
            ThrowNullException(array);

            return array.SelectSkip((a, inner) =>
                inner.SelectSkip((b, result) =>
                    result.SelectMany(c => GetTriplePermutations(a, b, c))));
        }

 private static IEnumerable<T> SelectSkip<T>(
            this IEnumerable<int> source,
            Func<int, IEnumerable<int>, IEnumerable<T>> func)
        {
            return source.SelectMany((a, i) =>
            {
                var inner = source.Skip(i + 1);
                return func(a, inner);
            });
        }

Я думаю, что я останусь со старой версией, хотя! : D

0 голосов
/ 22 октября 2019

Вы всегда можете определить метод расширения, который охватывает вашу логику и делает ваш код более читабельным.

Подробнее: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/how-to-implement-and-call-a-custom-extension-method

Псевдокод:

public static IEnumerable<IEnumerable<int>> GetTriplePermutations(tis IEnumerable<int> array)
{
    return array.SelectMany((a, i)).Skip(x + 1).SelectMany((b, j)).Skip(y + 1)
}

Вы можете вызвать эту функцию с помощью OddMethod(array).GetTriplePermutations();

...