public SliceItemIndexer(IList <T> source, int?from, int?to, int step) { this._source = source; var properties = SlicePropertiesCalculator.Calculate(from, to, step, source.Count); this._from = properties.from; this._step = properties.step; this._count = properties.count; }
public SliceDeleteItemIndexer(IList <T> source, int?from, int?to, int step) { this._source = source; var slice = SlicePropertiesCalculator.Calculate(from, to, step, source.Count); if (slice.count == 0 || slice.from >= source.Count) { this._from = source.Count; this._step = 1; this._skipCount = 0; this._takeCount = source.Count; } else { slice = SlicePropertiesCalculator.Abs(slice); this._from = slice.from; this._step = slice.step; this._skipCount = slice.count; this._boundary = slice.from + (slice.count - 1) * (slice.step - 1); this._takeCount = source.Count - Math.Min(slice.count, (source.Count - slice.from + slice.step - 1) / slice.step); } }
/// <summary> /// Performs slice on passed collection. /// </summary> /// <typeparam name="T">The type of the elements of source.</typeparam> /// <param name="source">Source collection.</param> /// <param name="from">First item index.</param> /// <param name="to">Exclusive boundary.</param> /// <param name="step">Increment index by.</param> /// <exception cref="ArgumentNullException">source is null.</exception> /// <exception cref="ArgumentException">step is equal to 0.</exception> /// <returns>Result of slice operation.</returns> public static IEnumerable <T> Slice <T>( this IEnumerable <T> source, int?from = null, int?to = null, int step = 1) { if (source == null) { throw new ArgumentNullException("source"); } { var sourceList = source as IList <T>; if (sourceList != null) { return(ProxiedListCreator.GetSlice(sourceList, from, to, step)); } } { var sourceCollection = source as ICollection; if (sourceCollection != null) { var count = sourceCollection.Count; var indexer = SlicePropertiesCalculator.Calculate(from, to, step, count); from = indexer.from; step = indexer.step; count = indexer.count; to = indexer.from + (step * count); if (to < 0) { to = null; } if (count == 0) { return(Enumerable.Empty <T>()); } } } if (step == 0) { throw new ArgumentException("Step cannot be zero."); } var fromValue = from ?? (step > 0 ? 0 : -1); var toIsPositiveOrNull = !(to < 0); if (step > 0) { if (fromValue >= 0) { if (toIsPositiveOrNull) { return(EnumerableSliceCases.PPP(source, fromValue, to, step)); } else { return(EnumerableSliceCases.PNP(source, fromValue, to.Value, step)); } } else { if (toIsPositiveOrNull) { return(EnumerableSliceCases.NPP(source, fromValue, to, step)); } else { return(EnumerableSliceCases.NNP(source, fromValue, to.Value, step)); } } } else { if (fromValue >= 0) { if (toIsPositiveOrNull) { return(EnumerableSliceCases.PPN(source, fromValue, to, step)); } else { return(EnumerableSliceCases.PNN(source, fromValue, to.Value, step)); } } else { if (toIsPositiveOrNull) { return(EnumerableSliceCases.NPN(source, fromValue, to, step)); } else { return(EnumerableSliceCases.NNN(source, fromValue, to.Value, step)); } } } }