I have two arrays of known lengths:
let left: [u8; 2] = [1, 2];
let right: [u8; 3] = [3, 4, 5];
My first attempt:
let whole: [u8; 5] = left + right;
fails with the error:
error[E0369]: cannot add `[u8; 2]` to `[u8; 3]`
--> /home/fadedbee/test.rs:25:29
|
25 | let whole: [u8; 5] = left + right;
| ---- ^ ----- [u8; 3]
| |
| [u8; 2]
Likewise:
let whole: [u8; 5] = left.concat(right);
fails with:
error[E0599]: the method `concat` exists for array `[u8; 2]`, but its trait bounds were not satisfied
--> /home/fadedbee/test.rs:25:29
|
25 | let whole: [u8; 5] = left.concat(right);
| ^^^^^^ method cannot be called on `[u8; 2]` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`<[u8] as std::slice::Concat<_>>::Output = _`
I'm currently using an expression of the form:
let whole: [u8; 5] = [left[0], left[1], right[0], right[1], right[2]];
but this is dozens of elements for my actual use-case and is prone to typos.
@Emoun kindly pointed out that I'd misused concat
.
Trying it properly:
let whole: [u8; 5] = [left, right].concat();
I get:
error[E0308]: mismatched types
--> /home/fadedbee/test.rs:32:31
|
32 | let whole: [u8; 5] = [left, right].concat();
| ^^^^^ expected an array with a fixed size of 2 elements, found one with 3 elements
|
= note: expected type `[u8; 2]`
found array `[u8; 3]`
How do I concatenate arrays of known lengths into a fixed length array?
In order to combine (concatenate) two arrays, we find its length stored in aLen and bLen respectively. Then, we create a new integer array result with length aLen + bLen . Now, in order to combine both, we copy each element in both arrays to result by using arraycopy() function.
JavaScript Array concat() Method Below is the example of Array concat() method to join three arrays. The arr. concat() method is used to merge two or more arrays together. This method does not alter the original arrays passed as arguments.
arange(2) is given. To concatenate the array of two different dimensions. The np. column_stack((array1, array2)) is used.
I guess there is a better answer, but you can do like this:
fn main() {
let left: [u8; 2] = [1, 2];
let right: [u8; 3] = [3, 4, 5];
let whole: [u8; 5] = {
let mut whole: [u8; 5] = [0; 5];
let (one, two) = whole.split_at_mut(left.len());
one.copy_from_slice(&left);
two.copy_from_slice(&right);
whole
};
println!("{:?}", whole);
}
Based on @yolenoyer's answer, this works, but requires cargo +nightly test
at the moment to enable const_evaluatable_checked
.
#![feature(const_generics)]
#![feature(const_evaluatable_checked)]
pub fn concat<T: Copy + Default, const A: usize, const B: usize>(a: &[T; A], b: &[T; B]) -> [T; A+B] {
let mut whole: [T; A+B] = [Default::default(); A+B];
let (one, two) = whole.split_at_mut(A);
one.copy_from_slice(a);
two.copy_from_slice(b);
whole
}
#[cfg(test)]
mod tests {
use super::concat;
#[test]
fn it_works() {
let a: [u8; 2] = [1, 2];
let b: [u8; 3] = [3, 4, 5];
let c: [u8; 5] = concat(&a, &b);
assert_eq!(c, [1, 2, 3, 4, 5]);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With