Files
PiliPlus/lib/utils/extension/iterable_ext.dart
My-Responsitories 7260a387f9 tweaks (#1821)
* opt: _onTapUp

* opt: set contains

* opt: elementAtOrNull
2026-02-02 20:12:12 +08:00

70 lines
1.5 KiB
Dart

extension NullableIterableExt<T> on Iterable<T>? {
bool get isNullOrEmpty => this == null || this!.isEmpty;
}
extension IterableExt<T> on Iterable<T> {
T? reduceOrNull(T Function(T value, T element) combine) {
Iterator<T> iterator = this.iterator;
if (!iterator.moveNext()) {
return null;
}
T value = iterator.current;
while (iterator.moveNext()) {
value = combine(value, iterator.current);
}
return value;
}
T? firstWhereOrNull(bool Function(T element) test) {
for (final element in this) {
if (test(element)) return element;
}
return null;
}
}
extension ListExt<T> on List<T> {
bool removeFirstWhere(bool Function(T) test) {
final index = indexWhere(test);
if (index != -1) {
removeAt(index);
return true;
}
return false;
}
List<R> fromCast<R>() {
return List<R>.from(this);
}
T findClosestTarget(
bool Function(T) test,
T Function(T, T) combine,
) {
return where(test).reduceOrNull(combine) ?? reduce(combine);
}
/// from [algorithms.lowerBoundBy].
int lowerBoundByKey<K extends Comparable<K>>(
K Function(T element) keyOf,
K key, [
int start = 0,
int? end,
]) {
end = RangeError.checkValidRange(start, end, length);
var min = start;
var max = end;
while (min < max) {
var mid = min + ((max - min) >> 1);
var element = this[mid];
var comp = keyOf(element).compareTo(key);
if (comp < 0) {
min = mid + 1;
} else {
max = mid;
}
}
return min;
}
}