#c_sharp #linq
Имеется массив. Нужно выбрать из него 3 последовательно расположенных элемента, произведение которых равно заданному числу Number при помощи Linq-запроса. Ниже приведен пример решения задачи с использованием обычного цикла. Кто может помочь с Linq? for (int i = 0; i < ArraySimple.Length - 2; i++) { if (ArraySimple[i] * ArraySimple[i + 1] * ArraySimple[i + 2] == Number) { Factor1 = ArraySimple[i]; Factor2 = ArraySimple[i + 1]; Factor3 = ArraySimple[i + 2]; return true; } }
Ответы
Ответ 1
Для начала, не стоит пользоваться LINQ лишь ради LINQ. Если в вашем коде сравнение троек лишь одно, сделайте циклом. Однако, код на LINQ может быть более эффективным и выразительным, поэтому если в вашем коде подобное встречается часто, стоит написать следующую LINQ-обёртку (переделана из используемого Pairwise): public static class EnumerableExtensions { public static IEnumerableTriplewise ( this IEnumerable sequence, Func selector) { using (var it = sequence.GetEnumerator()) { if (!it.MoveNext()) yield break; T prevprev = it.Current; if (!it.MoveNext()) yield break; T prev = it.Current; while (it.MoveNext()) yield return selector(prevprev, prevprev = prev, prev = it.Current); } } } Имея это, ваш код легко переписать так: ArraySimple.Triplewise((v1, v2, v3) => v1 * v2 * v3 == Number ? Tuple.Create(v1, v2, v3) : null) .Where(triple => triple != null); Так код стал понятнее, правда? Пример: var ArraySimple = new[] { 2, 3, 2, 6, 1, 12, 1 }; var Number = 12; var triples = ArraySimple.Triplewise((v1, v2, v3) => v1 * v2 * v3 == Number ? Tuple.Create(v1, v2, v3) : null) .Where(triple => triple != null); foreach (var triple in triples) { Console.WriteLine("{0} * {1} * {2} = {3}", triple.Item1, triple.Item2, triple.Item3, Number); } выдаёт 2 * 3 * 2 = 12 2 * 6 * 1 = 12 1 * 12 * 1 = 12 Ответ 2
Код вышел слишком широким, чтобы писать здесь, поэтому отвечаю через сервис сниппетов. Данный вариант не требует того, чтобы исходная коллекция была массивом, но с PLINQ использовать, наверное, не стоит.Ответ 3
Если утверждается, что исходник - массив, а не абстрактный Enumerable тогда такой способ сработает: // arr - заданый массив arr.Skip(2) .Select((it,ind) => new { Num1 = arr[ind], Num2 = arr[ind+1], Num3 = arr[ind+2], }) .Where((it)=> it.Num1 * it.Num2 * it.Num3 == Number)Ответ 4
Cтруктура результат : struct ResultInt { public int FirstNumber; public int SecondNumber; public int ThirdNumber; } Метод класса: public static IEnumerableGetThreeNumbers(int[] InputArray, int Number) { // создадим запрос линку IEnumerable GetThreeNumbersLinq = (from Item in InputArray where (Array.IndexOf(InputArray, Item) < SomeArray.Length - 2) && (SomeArray[Array.IndexOf(InputArray, Item)] * SomeArray[Array.IndexOf(InputArray, Item) + 1] * SomeArray[Array.IndexOf(InputArray, Item) + 2] == Number) select new ResultInt() { FirstNumber = InputArray[Array.IndexOf(InputArray, Item)], SecondNumber = InputArray[Array.IndexOf(InputArray, Item) + 1], ThirdNumber = InputArray[Array.IndexOf(InputArray, Item) + 2], } ); } Вызов : int[] InputArray = null; int Number= 0; List SomeResult = GetThreeNumbers(InputArray, Number).ToList (); foreach (ResultInt item in SomeResult) { MessageBox.Show(item.FirstNumber.ToString() + " " + item.SecondNumber.ToString() + " "+item.ThirdNumber.ToString()); }
Комментариев нет:
Отправить комментарий