Есть метод переопределения, который вытаскивает последние n-элементов списка. Допустим списке у меня 10 элементов, а хочу я получить 100 элементов. Как заполнить эти 90 элементов нулями?
public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int takeCount)
{
if (source == null) { throw new ArgumentNullException("source"); }
if (takeCount < 0) { throw new ArgumentOutOfRangeException("takeCount", "must not be negative"); }
if (takeCount == 0) { yield break; }
T[] result = new T[takeCount];
int i = 0;
int sourceCount = 0;
foreach (T element in source)
{
result[i] = element;
i = (i + 1) % takeCount;
sourceCount++;
}
if (sourceCount < takeCount)
{
takeCount = sourceCount;
i = 0;
}
for (int j = 0; j < takeCount; ++j)
{
yield return result[(i + j) % takeCount];
}
}
Для того, чтобы вернуть некоторое количество элементов с конца последовательности, нам нужно перебрать все ее элементы, поэтому считаю приемлемым переписать ваш метод таким образом:
public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int takeCount)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (takeCount < 0) throw new ArgumentOutOfRangeException(nameof(takeCount), "must not be negative");
if (takeCount == 0) return Enumerable.Empty<T>();
return source.Reverse().Take(takeCount).Reverse();
}
Ну и, т. к. заведомо count + takeCount >= takeCount
, можно дополнить исходную последовательность значениями def
в количестве takeCount
шт.:
public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int takeCount, T def = default)
{
...
return source.Reverse().Take(takeCount).Reverse()
.Concat(Enumerable.Repeat(def, takeCount)).Take(takeCount);
}
Еще один вариант, который не будет хранить абсолютно все элементы входной последовательности без необходимости:
public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int takeCount, T def = default)
{
...
var queue = new Queue<T>(takeCount);
foreach (var item in source)
{
if (queue.Count == takeCount) queue.Dequeue();
queue.Enqueue(item);
}
return queue.Concat(Enumerable.Repeat(def, Math.Max(0, takeCount - queue.Count)));
}
Очередь (System.Collections.Generic.Queue<T>
) использует внутри такой же подход с "циклическим массивом", что и у вас.
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Теоретический вопросЕсли нам нужно синхронизировать потоки, то в большинстве случаев наверное достаточно lock, это почти то же самое, что...
Я получил список категорий из БДДалее мне нужно получить из соседней таблицы все топики, которые относятся к данной категории