Add a zip method to arrays (#947)

This commit is contained in:
Laurenz Stampfl 2023-04-25 11:22:20 +02:00 committed by GitHub
parent d5d98b67a8
commit f38989358e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 0 deletions

View File

@ -620,6 +620,16 @@ for loop.
- returns: array
### zip()
Zips the array with another array. If the two arrays are of unequal length, it
will only zip up until the last element of the smaller array and the remaining
elements will be ignored. The return value is an array where each element is yet
another array of size 2.
- other: array (positional, required)
The other array which should be zipped with the current one.
- returns: array
### fold()
Folds all items into a single value using an accumulator function.

View File

@ -306,6 +306,18 @@ impl Array {
Ok(result)
}
/// Zips the array with another array. If the two arrays are of unequal length, it will only
/// zip up until the last element of the smaller array and the remaining elements will be
/// ignored. The return value is an array where each element is yet another array of size 2.
pub fn zip(&self, other: Array) -> Array {
self.iter()
.zip(other)
.map(|(first, second)| {
Value::Array(Array::from_vec(eco_vec![first.clone(), second]))
})
.collect()
}
/// Return a sorted version of this array, optionally by a given key function.
///
/// Returns an error if two values could not be compared or if the key function (if given)

View File

@ -118,6 +118,7 @@ pub fn call(
array.join(sep, last).at(span)?
}
"sorted" => Value::Array(array.sorted(vm, span, args.named("key")?)?),
"zip" => Value::Array(array.zip(args.expect("other")?)),
"enumerate" => Value::Array(array.enumerate()),
_ => return missing(),
},
@ -319,6 +320,7 @@ pub fn methods_on(type_name: &str) -> &[(&'static str, bool)] {
("slice", true),
("sorted", false),
("enumerate", false),
("zip", true),
],
"dictionary" => &[
("at", true),

View File

@ -223,6 +223,17 @@
#test((2, 1, 3, -10, -5, 8, 6, -7, 2).sorted(key: x => x), (-10, -7, -5, 1, 2, 2, 3, 6, 8))
#test((2, 1, 3, -10, -5, 8, 6, -7, 2).sorted(key: x => x * x), (1, 2, 2, 3, -5, 6, -7, 8, -10))
---
// Test the `zip` method.
#test(().zip(()), ())
#test((1,).zip(()), ())
#test((1,).zip((2,)), ((1, 2),))
#test((1, 2).zip((3, 4)), ((1, 3), (2, 4)))
#test((1, 2, 3, 4).zip((5, 6)), ((1, 5), (2, 6)))
#test(((1, 2), 3).zip((4, 5)), (((1, 2), 4), (3, 5)))
#test((1, "hi").zip((true, false)), ((1, true), ("hi", false)))
---
// Error: 32-37 cannot divide by zero
#(1, 2, 0, 3).sorted(key: x => 5 / x)