nc-photos/np_collection/lib/src/list_extension.dart

95 lines
2.6 KiB
Dart
Raw Normal View History

2022-01-02 01:25:50 +08:00
import 'dart:math' as math;
2022-06-06 16:33:56 +08:00
import 'package:collection/collection.dart';
2023-08-25 23:29:27 +08:00
import 'package:np_math/np_math.dart';
2022-06-06 16:33:56 +08:00
2021-04-10 12:28:12 +08:00
extension ListExtension<T> on List<T> {
Iterable<T> takeIndex(List<int> indexes) => indexes.map((e) => this[e]);
2022-01-02 01:25:50 +08:00
2022-10-11 00:05:53 +08:00
List<T> slice(int start, [int? stop, int step = 1]) {
assert(step > 0);
2022-01-02 01:25:50 +08:00
if (start < 0) {
start = math.max(length + start, 0);
}
if (stop != null && stop < 0) {
stop = math.max(length + stop, 0);
}
if (start >= length) {
return [];
} else if (stop == null) {
2022-10-11 00:05:53 +08:00
final sub = sublist(start);
if (step <= 1) {
return sub;
} else {
return sub.whereIndexed((index, _) => index % step == 0).toList();
}
2022-01-02 01:25:50 +08:00
} else if (start >= stop) {
return [];
} else {
2022-10-11 00:05:53 +08:00
final sub = sublist(start, math.min(stop, length));
if (step <= 1) {
return sub;
} else {
return sub.whereIndexed((index, _) => index % step == 0).toList();
}
2022-01-02 01:25:50 +08:00
}
}
2022-06-06 16:33:56 +08:00
void stableSort([int Function(T a, T b)? compare]) {
mergeSort(this, compare: compare);
}
2022-06-06 18:06:15 +08:00
/// In-place transform and return this
///
/// Since the elements are in-place transformed, they have to share the same
/// type
List<T> transform(T Function(T element) fn) {
for (final i in 0.until(length)) {
this[i] = fn(this[i]);
}
return this;
}
Future<List<U>> asyncMap<U>(Future<U> Function(T element) fn) {
return Stream.fromIterable(this).asyncMap(fn).toList();
}
/// [map] with access to nearby elements
///
/// Does not work well with nullable elements as prev and next return null for
/// the first and last element
Iterable<U> map3<U>(U Function(T e, T? prev, T? next) toElement) sync* {
for (var i = 0; i < length; ++i) {
yield toElement(
this[i],
i == 0 ? null : this[i - 1],
i == length - 1 ? null : this[i + 1],
);
}
}
/// [expand] with access to nearby elements
///
/// Does not work well with nullable elements as prev and next return null for
/// the first and last element
Iterable<U> expand3<U>(
Iterable<U> Function(T e, T? prev, T? next) toElements) sync* {
for (var i = 0; i < length; ++i) {
yield* toElements(
this[i],
i == 0 ? null : this[i - 1],
i == length - 1 ? null : this[i + 1],
);
}
}
2024-05-25 15:51:42 +08:00
List<T> added(T value) => toList()..add(value);
List<T> removed(T value) => toList()..remove(value);
2024-10-07 01:15:45 +08:00
List<T> removedAt(int index) => toList()..removeAt(index);
List<T> removedWhere(bool Function(T element) test) =>
toList()..removeWhere(test);
2021-04-10 12:28:12 +08:00
}