Skip to content

Commit 01aafb4

Browse files
committed
add @array.zip and @array.zip_with
1 parent 9e073ba commit 01aafb4

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

array/array.mbt

+63
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,69 @@ pub fn last[A](self : Array[A]) -> A? {
202202
}
203203
}
204204
205+
///| Zips two arrays into a single array of tuples.
206+
///
207+
/// Parameters:
208+
///
209+
/// * `l` : The first array.
210+
/// * `r` : The second array.
211+
///
212+
/// Returns an array of tuples, where each tuple contains corresponding elements
213+
/// from the two input arrays.
214+
///
215+
/// Example:
216+
///
217+
/// ```moonbit
218+
/// test "zip" {
219+
/// let arr1 = [1, 2, 3]
220+
/// let arr2 = ['a', 'b', 'c']
221+
/// inspect!(zip(arr1, arr2), content="[(1, 'a'), (2, 'b'), (3, 'c')]")
222+
/// }
223+
/// ```
224+
pub fn zip[A, B](l : Array[A], r : Array[B]) -> Array[(A, B)] {
225+
let length = if l.length() < r.length() { l.length() } else { r.length() }
226+
let arr = Array::new(capacity=length)
227+
for i = 0; i < length; i = i + 1 {
228+
arr.push((l[i], r[i]))
229+
} else {
230+
return arr
231+
}
232+
}
233+
234+
///| Zips two arrays into a single array by applying a function to each pair of elements.
235+
///
236+
/// Parameters:
237+
///
238+
/// * `l` : The first array.
239+
/// * `r` : The second array.
240+
/// * `merge` : A function that takes two arguments, one from each array, and returns a value.
241+
///
242+
/// Returns an array containing the results of applying the function to each pair of elements.
243+
///
244+
/// Example:
245+
///
246+
/// ```moonbit
247+
/// test "zip_with" {
248+
/// let arr1 = [1, 2, 3]
249+
/// let arr2 = [4, 5, 6]
250+
/// let add = fn(a, b) { a + b }
251+
/// inspect!(zip_with(arr1, arr2, merge=add), content="[5, 7, 9]")
252+
/// }
253+
/// ```
254+
pub fn zip_with[A, B, C](
255+
l : Array[A],
256+
r : Array[B],
257+
merge~ : (A, B) -> C
258+
) -> Array[C] {
259+
let length = if l.length() < r.length() { l.length() } else { r.length() }
260+
let arr = Array::new(capacity=length)
261+
for i = 0; i < length; i = i + 1 {
262+
arr.push(merge(l[i], r[i]))
263+
} else {
264+
return arr
265+
}
266+
}
267+
205268
///|
206269
pub impl[X : @quickcheck.Arbitrary] @quickcheck.Arbitrary for Array[X] with arbitrary(
207270
size,

array/array.mbti

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package moonbitlang/core/array
33
alias @moonbitlang/core/quickcheck as @quickcheck
44

55
// Values
6+
fn zip[A, B](Array[A], Array[B]) -> Array[(A, B)]
7+
8+
fn zip_with[A, B, C](Array[A], Array[B], merge~ : (A, B) -> C) -> Array[C]
69

710
// Types and methods
811
impl FixedArray {

array/array_test.mbt

+40
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,46 @@ test "Array::last" {
555555
inspect!([1].last(), content="Some(1)")
556556
}
557557

558+
test "zip" {
559+
// Test with two non-empty arrays
560+
let arr1 = [1, 2, 3]
561+
let arr2 = ['a', 'b', 'c']
562+
inspect!(zip(arr1, arr2), content="[(1, 'a'), (2, 'b'), (3, 'c')]")
563+
564+
// Test with arrays of different lengths
565+
let arr3 = [1, 2]
566+
let arr4 = ["a", "b", "c"]
567+
inspect!(
568+
zip(arr3, arr4),
569+
content=
570+
#|[(1, "a"), (2, "b")]
571+
,
572+
)
573+
574+
// Test with an empty array
575+
let arr5 : Array[Int] = []
576+
let arr6 = ["a", "b", "c"]
577+
inspect!(zip(arr5, arr6), content="[]")
578+
}
579+
580+
test "zip_with" {
581+
// Test with two non-empty arrays and a function
582+
let arr1 = [1, 2, 3]
583+
let arr2 = [4, 5, 6]
584+
let add = fn(a, b) { a + b }
585+
inspect!(zip_with(arr1, arr2, merge=add), content="[5, 7, 9]")
586+
587+
// Test with arrays of different lengths and a function
588+
let arr3 = [1, 2]
589+
let arr4 = [4, 5, 6]
590+
inspect!(zip_with(arr3, arr4, merge=add), content="[5, 7]")
591+
592+
// Test with an empty array and a function
593+
let arr5 : Array[Int] = []
594+
let arr6 = [4, 5, 6]
595+
inspect!(zip_with(arr5, arr6, merge=add), content="[]")
596+
}
597+
558598
test "arbitrary" {
559599
let arr : Array[Array[Int]] = @quickcheck.samples(20)
560600
inspect!(arr[5:9], content="[[0], [0], [0], [0, 0, 0]]")

0 commit comments

Comments
 (0)