diff --git a/cspell.json b/cspell.json index 1174a56dd33..c1cc19f8962 100644 --- a/cspell.json +++ b/cspell.json @@ -60,6 +60,7 @@ "combinators", "compinit", "comptime", + "concat", "cpus", "cranelift", "critesjosh", diff --git a/docs/docs/noir/concepts/data_types/arrays.md b/docs/docs/noir/concepts/data_types/arrays.md index 289145a8c4d..fd9428b97b5 100644 --- a/docs/docs/noir/concepts/data_types/arrays.md +++ b/docs/docs/noir/concepts/data_types/arrays.md @@ -255,6 +255,41 @@ fn main() { } ``` +### concat + +Concatenates this array with another array. + +```rust +fn concat(self, array2: [T; M]) -> [T; N + M] +``` + +```rust +fn main() { + let arr1 = [1, 2, 3, 4]; + let arr2 = [6, 7, 8, 9, 10, 11]; + let concatenated_arr = arr1.concat(arr2); + assert(concatenated_arr == [1, 2, 3, 4, 6, 7, 8, 9, 10, 11]); +} +``` + +### concat3 + +Concatenates this array with another array. + +```rust +fn concat3(self, array2: [T; M], array3: [T; L]) -> [T; N + M + L] +``` + +```rust +fn main() { + let arr1 = [1, 2, 3]; + let arr2 = [4, 5, 6]; + let arr3 = [7, 8, 9]; + let concatenated_arr = arr1.concat3(arr2, arr3); + assert(concatenated_arr == [1, 2, 3, 4, 5, 6, 7, 8, 9]); +} +``` + ### as_str_unchecked Converts a byte array of type `[u8; N]` to a string. Note that this performs no UTF-8 validation - diff --git a/noir_stdlib/src/array/mod.nr b/noir_stdlib/src/array/mod.nr index 85cc0580aae..d4359f1c5f3 100644 --- a/noir_stdlib/src/array/mod.nr +++ b/noir_stdlib/src/array/mod.nr @@ -136,6 +136,61 @@ impl [T; N] { } ret } + + /// Concatenates this array with another array. + /// + /// Example: + /// + /// ```noir + /// fn main() { + /// let arr1 = [1, 2, 3, 4]; + /// let arr2 = [6, 7, 8, 9, 10, 11]; + /// let concatenated_arr = arr1.concat(arr2); + /// assert(concatenated_arr == [1, 2, 3, 4, 6, 7, 8, 9, 10, 11]); + /// } + /// ``` + pub fn concat(self, array2: [T; M]) -> [T; N + M] { + let mut result = [self[0]; N + M]; + for i in 1..N { + result[i] = self[i]; + } + for i in 0..M { + result[i + N] = array2[i]; + } + result + } + + /// Concatenates this array with two other arrays. + /// + /// For unconstrained functions, this is more efficient than calling + /// `arr1.concat(arr2.concat(arr3))`. + /// + /// Example: + /// + /// ```noir + /// fn main() { + /// let arr1 = [1, 2, 3]; + /// let arr2 = [4, 5, 6]; + /// let arr3 = [7, 8, 9]; + /// let concatenated_arr = arr1.concat3(arr2, arr3); + /// assert(concatenated_arr == [1, 2, 3, 4, 5, 6, 7, 8, 9]); + /// } + /// ``` + pub fn concat3(self, array2: [T; M], array3: [T; L]) -> [T; N + M + L] { + let mut result = [self[0]; N + M + L]; + for i in 1..N { + result[i] = self[i]; + } + let mut offset = N; + for i in 0..M { + result[offset + i] = array2[i]; + } + offset += M; + for i in 0..L { + result[offset + i] = array3[i]; + } + result + } } impl [T; N] @@ -232,4 +287,21 @@ mod test { fn map_empty() { assert_eq([].map(|x| x + 1), []); } + + #[test] + fn concat() { + let arr1 = [1, 2, 3, 4]; + let arr2 = [6, 7, 8, 9, 10, 11]; + let concatenated_arr = arr1.concat(arr2); + assert(concatenated_arr == [1, 2, 3, 4, 6, 7, 8, 9, 10, 11]); + } + + #[test] + fn concat3() { + let arr1 = [1, 2, 3]; + let arr2 = [4, 5, 6]; + let arr3 = [7, 8, 9]; + let concatenated_arr = arr1.concat3(arr2, arr3); + assert(concatenated_arr == [1, 2, 3, 4, 5, 6, 7, 8, 9]); + } }