Add chunks method to array (#3539)

Co-authored-by: Laurenz <laurmaedje@gmail.com>
This commit is contained in:
frozolotl 2024-03-04 10:03:35 +01:00 committed by GitHub
parent 086bca9576
commit 879bd1a1ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 51 additions and 1 deletions

View File

@ -1,6 +1,6 @@
use std::cmp::Ordering;
use std::fmt::{Debug, Formatter};
use std::num::NonZeroI64;
use std::num::{NonZeroI64, NonZeroUsize};
use std::ops::{Add, AddAssign};
use ecow::{eco_format, EcoString, EcoVec};
@ -724,6 +724,36 @@ impl Array {
Array(vec)
}
/// Splits an array into non-overlapping chunks, starting at the beginning,
/// ending with a single remainder chunk.
///
/// All chunks but the last have `chunk-size` elements.
/// If `exact` is set to `{true}`, the remainder is dropped if it
/// contains less than `chunk-size` elements.
///
/// ```example
/// #let array = (1, 2, 3, 4, 5, 6, 7, 8)
/// #array.chunks(3)
/// #array.chunks(3, exact: true)
/// ```
#[func]
pub fn chunks(
self,
/// How many elements each chunk may at most contain.
chunk_size: NonZeroUsize,
/// Whether to keep the remainder if its size is less than `chunk-size`.
#[named]
#[default(false)]
exact: bool,
) -> Array {
let to_array = |chunk| Array::from(chunk).into_value();
if exact {
self.0.chunks_exact(chunk_size.get()).map(to_array).collect()
} else {
self.0.chunks(chunk_size.get()).map(to_array).collect()
}
}
/// Return a sorted version of this array, optionally by a given key
/// function. The sorting algorithm used is stable.
///

View File

@ -236,6 +236,26 @@
#test((1, 2).intersperse("a"), (1, "a", 2))
#test((1, 2, "b").intersperse("a"), (1, "a", 2, "a", "b"))
---
// Test the `chunks` method.
#test(().chunks(10), ())
#test((1, 2, 3).chunks(10), ((1, 2, 3),))
#test((1, 2, 3, 4, 5, 6).chunks(3), ((1, 2, 3), (4, 5, 6)))
#test((1, 2, 3, 4, 5, 6, 7, 8).chunks(3), ((1, 2, 3), (4, 5, 6), (7, 8)))
#test(().chunks(10, exact: true), ())
#test((1, 2, 3).chunks(10, exact: true), ())
#test((1, 2, 3, 4, 5, 6).chunks(3, exact: true), ((1, 2, 3), (4, 5, 6)))
#test((1, 2, 3, 4, 5, 6, 7, 8).chunks(3, exact: true), ((1, 2, 3), (4, 5, 6)))
---
// Error: 19-20 number must be positive
#(1, 2, 3).chunks(0)
---
// Error: 19-21 number must be positive
#(1, 2, 3).chunks(-5)
---
// Test the `sorted` method.
#test(().sorted(), ())