I have a byte vector and want to replace every [1, 2, 3]
with [4, 5, 6]
. How is this possible in Rust?
let mut buf = vec![1, 2, 3, 7, 8];
// ?
assert_eq!(buf, vec![4, 5, 6, 7, 8]);
This function can do the job:
fn replace_slice<T>(source: &mut [T], from: &[T], to: &[T])
where
T: Clone + PartialEq,
{
let iteration = if source.starts_with(from) {
source[..from.len()].clone_from_slice(to);
from.len()
} else {
1
};
if source.len() > from.len() {
replace_slice(&mut source[iteration..], from, to);
}
}
This function is recursive but you can rewrite it using loops as well.
Example 1:
fn main() {
let mut buf = vec![1, 2, 3, 7, 8, 1, 2, 3];
replace_slice(&mut buf[..], &[1, 2, 3], &[4, 5, 6]);
assert_eq!(buf, vec![4, 5, 6, 7, 8, 4, 5, 6]);
}
Playground
Example 2: (From the comment by trentcl)
fn main() {
let mut buf = vec![1, 2, 3, 3, 4, 1, 2, 3];
replace_slice(&mut buf[..], &[1, 2, 3], &[5, 1, 2]);
assert_eq!(buf, vec![5, 1, 2, 3, 4, 5, 1, 2]);
}
Playground
This works when the slices have different lengths (similar to replace
for str
):
fn replace<T>(source: &[T], from: &[T], to: &[T]) -> Vec<T>
where
T: Clone + PartialEq
{
let mut result = source.to_vec();
let from_len = from.len();
let to_len = to.len();
let mut i = 0;
while i + from_len <= result.len() {
if result[i..].starts_with(from) {
result.splice(i..i + from_len, to.iter().cloned());
i += to_len;
} else {
i += 1;
}
}
result
}
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