|
@@ -102,6 +102,16 @@ namespace Invercargill {
|
|
|
return count;
|
|
|
}
|
|
|
|
|
|
+ public virtual ulong long_count(PredicateDelegate<T>? predicate = null) {
|
|
|
+ var enumerable = this;
|
|
|
+ if(predicate != null) {
|
|
|
+ enumerable = this.where(predicate);
|
|
|
+ }
|
|
|
+ ulong count = 0;
|
|
|
+ enumerable.iterate(i => count++);
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
public virtual bool any(PredicateDelegate<T>? predicate = null) {
|
|
|
var result = false;
|
|
|
var p = resolve_nullable_predicate(predicate);
|
|
@@ -210,10 +220,30 @@ namespace Invercargill {
|
|
|
return new Skip<T>(this, count);
|
|
|
}
|
|
|
|
|
|
+ public virtual Enumerable<T> skip_last(int count) {
|
|
|
+ return Iterate.deferred<T>(() => {
|
|
|
+ var buffer = to_immutable_buffer();
|
|
|
+ return buffer.take(int.max(0, (int)buffer.length - count));
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO: This one could realistically be a modifier using a ring buffer so we don't have to
|
|
|
+ // buffer the whole sequence
|
|
|
+ public virtual Enumerable<T> take_last(int count) {
|
|
|
+ return Iterate.deferred<T>(() => {
|
|
|
+ var buffer = to_immutable_buffer();
|
|
|
+ return buffer.skip(int.max(0, (int)buffer.length - count));
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
public virtual Enumerable<TOut> cast<TOut>() {
|
|
|
return select<TOut>(i => (TOut)i);
|
|
|
}
|
|
|
|
|
|
+ public virtual Enumerable<TOut> of_type<TOut>() {
|
|
|
+ return where(i => i is TOut).cast<TOut>();
|
|
|
+ }
|
|
|
+
|
|
|
public virtual Enumerable<TOut> parallel_select<TOut>(owned TransformDelegate<T, TOut> transform, uint workers = 0) {
|
|
|
var actual_workers = workers;
|
|
|
if(actual_workers < 1) {
|
|
@@ -457,6 +487,30 @@ namespace Invercargill {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+ public virtual T element_at(uint index) throws SequenceError {
|
|
|
+ T item = null;
|
|
|
+ var tracker = get_tracker();
|
|
|
+ for(uint i = 0; i <= index; i++) {
|
|
|
+ if(!tracker.has_next()) {
|
|
|
+ throw new SequenceError.TOO_FEW_ELEMENTS(@"The sequence contains less than $(index+1) element(s)");
|
|
|
+ }
|
|
|
+ item = tracker.get_next();
|
|
|
+ }
|
|
|
+ return item;
|
|
|
+ }
|
|
|
+
|
|
|
+ public virtual T? element_at_or_default(uint index) {
|
|
|
+ T item = null;
|
|
|
+ var tracker = get_tracker();
|
|
|
+ for(uint i = 0; i <= index; i++) {
|
|
|
+ if(!tracker.has_next()) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ item = tracker.get_next();
|
|
|
+ }
|
|
|
+ return item;
|
|
|
+ }
|
|
|
+
|
|
|
public virtual string to_string(StringifyDelegate<T>? stringifier = null, string seperator = "") {
|
|
|
bool is_first = true;
|
|
|
stringifier = stringifier ?? Operators.stringify<T>();
|