Skip to content

Commit 463709b

Browse files
author
Abbas Hosseini
committed
Add intersperse method to Iterable extension for efficient element separation
Implement a new `intersperse` method that lazily inserts a specified separator between elements of an iterable. This method is memory-efficient and utilizes a generator for performance. Include comprehensive tests covering various scenarios, including empty iterables and different separator types.
1 parent b59ecf4 commit 463709b

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

pkgs/collection/lib/src/iterable_extensions.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,33 @@ extension IterableExtension<T> on Iterable<T> {
613613
yield slice;
614614
}
615615
}
616+
617+
/// Lazily returns a new iterable where a [separator] is placed between each
618+
/// element of this iterable.
619+
///
620+
/// This is the most performant way to implement this functionality because
621+
/// it uses a generator (`sync*`) and does not create a new list upfront,
622+
/// making it memory-efficient for iterables of any size.
623+
///
624+
/// Example:
625+
/// ```dart
626+
/// final numbers = [1, 2, 3];
627+
/// final withSeparators = numbers.intersperse(0);
628+
/// print(withSeparators.toList()); // Output: [1, 0, 2, 0, 3]
629+
/// ```
630+
///
631+
/// The resulting iterable is lazy. It only computes the next value when
632+
/// it's requested.
633+
Iterable<T> intersperse(T separator) sync* {
634+
final iterator = this.iterator;
635+
if (iterator.moveNext()) {
636+
yield iterator.current;
637+
while (iterator.moveNext()) {
638+
yield separator;
639+
yield iterator.current;
640+
}
641+
}
642+
}
616643
}
617644

618645
/// Extensions that apply to iterables with a nullable element type.

pkgs/collection/test/extensions_test.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,33 @@ void main() {
12241224
);
12251225
});
12261226
});
1227+
group('.intersperse', () {
1228+
test('empty', () {
1229+
expect(iterable(<int>[]).intersperse(0), []);
1230+
});
1231+
test('single element', () {
1232+
expect(iterable([1]).intersperse(0), [1]);
1233+
});
1234+
test('two elements', () {
1235+
expect(iterable([1, 2]).intersperse(0), [1, 0, 2]);
1236+
});
1237+
test('multiple elements', () {
1238+
expect(iterable([1, 2, 3, 4]).intersperse(0), [1, 0, 2, 0, 3, 0, 4]);
1239+
});
1240+
test('with different separator types', () {
1241+
expect(iterable(['a', 'b', 'c']).intersperse('-'),
1242+
['a', '-', 'b', '-', 'c']);
1243+
expect(iterable([1.5, 2.5, 3.5]).intersperse(0.0),
1244+
[1.5, 0.0, 2.5, 0.0, 3.5]);
1245+
});
1246+
test('with nullable int separator', () {
1247+
expect(iterable([1, 2, 3]).intersperse(0), [1, 0, 2, 0, 3]);
1248+
});
1249+
test('with empty string separator', () {
1250+
expect(iterable(['a', 'b', 'c']).intersperse(''),
1251+
['a', '', 'b', '', 'c']);
1252+
});
1253+
});
12271254
});
12281255
group('of MapEntry', () {
12291256
group('.whereKey', () {

0 commit comments

Comments
 (0)