randomize<T> static method
Randomly selects elements from multiple lists while ensuring uniqueness.
Parameters:
root: A list of lists containing possible values.length: The desired number of elements in the result.initial: An optional list of initial values (default is empty).converter: A function to modify selected items before adding them.
Example:
List<List<String>> root = [
['A', 'B', 'C'],
['D', 'E'],
['F', 'G', 'H']
];
List<String> result = randomize(root, 5);
// Possible output: ['B', 'D', 'F', 'C', 'E']
Implementation
static List<T> randomize<T>(
Iterable<Iterable<T>> root, {
int? length,
List<T> initial = const [],
T Function(int index, T old)? converter,
}) {
if (root.isEmpty) return [];
final total = root.map((e) => e.length).reduce((a, b) => a + b);
length ??= total;
final random = Random();
List<T> randoms = [...initial];
for (int i = 0; i < root.length; i++) {
final items = root.elementAtOrNull(i);
if (items == null || items.isEmpty) continue;
int index = random.nextInt(items.length);
final item = items.elementAtOrNull(index);
if (item == null) continue;
if (length <= total && randoms.contains(item)) continue;
randoms.add(
converter != null ? converter(randoms.length + 1, item) : item,
);
}
if (randoms.length == length) return randoms;
if (randoms.length > length) return randoms.take(length).toList();
return randomize(
root,
length: length,
initial: randoms,
converter: converter,
);
}