Add linux deb dependencies Add backup recovery strategy select Support custom text scaling Optimize the display of different text scale Optimize windows setup experience Optimize startTun performance Optimize android tv experience Optimize default option Optimize computed text size Optimize hyperOS freeform window Add developer mode Update core Optimize more details
114 lines
2.5 KiB
Dart
114 lines
2.5 KiB
Dart
extension IterableExt<T> on Iterable<T> {
|
|
Iterable<T> separated(T separator) sync* {
|
|
final iterator = this.iterator;
|
|
if (!iterator.moveNext()) return;
|
|
|
|
yield iterator.current;
|
|
|
|
while (iterator.moveNext()) {
|
|
yield separator;
|
|
yield iterator.current;
|
|
}
|
|
}
|
|
|
|
Iterable<List<T>> chunks(int size) sync* {
|
|
if (length == 0) return;
|
|
var iterator = this.iterator;
|
|
while (iterator.moveNext()) {
|
|
var chunk = [iterator.current];
|
|
for (var i = 1; i < size && iterator.moveNext(); i++) {
|
|
chunk.add(iterator.current);
|
|
}
|
|
yield chunk;
|
|
}
|
|
}
|
|
|
|
Iterable<T> fill(
|
|
int length, {
|
|
required T Function(int count) filler,
|
|
}) sync* {
|
|
int count = 0;
|
|
for (var item in this) {
|
|
yield item;
|
|
count++;
|
|
if (count >= length) return;
|
|
}
|
|
while (count < length) {
|
|
yield filler(count);
|
|
count++;
|
|
}
|
|
}
|
|
|
|
Iterable<T> takeLast({int count = 50}) {
|
|
if (count <= 0) return Iterable.empty();
|
|
return count >= length ? this : toList().skip(length - count);
|
|
}
|
|
}
|
|
|
|
extension ListExt<T> on List<T> {
|
|
void truncate(int maxLength) {
|
|
assert(maxLength > 0);
|
|
if (length > maxLength) {
|
|
removeRange(0, length - maxLength);
|
|
}
|
|
}
|
|
|
|
List<T> intersection(List<T> list) {
|
|
return where((item) => list.contains(item)).toList();
|
|
}
|
|
|
|
List<List<T>> batch(int maxConcurrent) {
|
|
final batches = (length / maxConcurrent).ceil();
|
|
final List<List<T>> res = [];
|
|
for (int i = 0; i < batches; i++) {
|
|
if (i != batches - 1) {
|
|
res.add(sublist(i * maxConcurrent, maxConcurrent * (i + 1)));
|
|
} else {
|
|
res.add(sublist(i * maxConcurrent, length));
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
List<T> safeSublist(int start) {
|
|
if (start <= 0) return this;
|
|
if (start > length) return [];
|
|
return sublist(start);
|
|
}
|
|
}
|
|
|
|
extension DoubleListExt on List<double> {
|
|
int findInterval(num target) {
|
|
if (isEmpty) return -1;
|
|
if (target < first) return -1;
|
|
if (target >= last) return length - 1;
|
|
|
|
int left = 0;
|
|
int right = length - 1;
|
|
|
|
while (left <= right) {
|
|
int mid = left + (right - left) ~/ 2;
|
|
|
|
if (mid == length - 1 ||
|
|
(this[mid] <= target && target < this[mid + 1])) {
|
|
return mid;
|
|
} else if (target < this[mid]) {
|
|
right = mid - 1;
|
|
} else {
|
|
left = mid + 1;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
extension MapExt<K, V> on Map<K, V> {
|
|
updateCacheValue(K key, V Function() callback) {
|
|
if (this[key] == null) {
|
|
this[key] = callback();
|
|
}
|
|
return this[key];
|
|
}
|
|
}
|