I want to remove duplicate elements from an array:
use itertools::Itertools;
use std::collections::HashSet;
#[derive(Debug)]
struct Person {
name: String,
age: u32,
}
fn main() {
let arr = [
Person { name: "aaa".to_string(), age: 10 },
Person { name: "bbb".to_string(), age: 20 },
Person { name: "bbb".to_string(), age: 20 },
Person { name: "ccc".to_string(), age: 30 },
];
// Way 1:
let arr2 = {
let names: Vec<_> = arr.iter().map(|v| v.name.clone()).unique().collect();
names
.iter()
.map(|name| arr.iter().find(|person| &person.name == name).unwrap())
.collect::<Vec<_>>()
};
dbg!(arr2);
// Way 2:
let arr2 = {
let mut names = HashSet::new();
arr.iter()
.filter(|p| names.insert(p.name.clone()))
.collect::<Vec<_>>()
};
dbg!(arr2);
/*
expect:
[
Person{name: "aaa".to_string(), age: 10},
Person{name: "bbb".to_string(), age: 20},
Person{name: "ccc".to_string(), age: 30},
]
*/
}
Way 2 is simple compared to way 1, but is there anything simpler?
There's a difference between the dedup and unique method in Itertools, where the former operates on contiguous elements, i.e:
[1, 2, 2, 3, 4, 3, 2, 1].iter().dedup() // [1, 2, 3, 4, 3, 2, 1]
[1, 2, 2, 3, 4, 3, 2, 1].iter().unique() // [1, 2, 3, 4]
If you're looking to have unique elements by name, unique_by might do:
use itertools::Itertools;
#[derive(Debug)]
struct Person {
name: String,
age: u32,
}
fn main() {
let arr = [
Person { name: "aaa".to_string(), age: 10 },
Person { name: "bbb".to_string(), age: 20 },
Person { name: "bbb".to_string(), age: 20 }, // Duplicate
Person { name: "ccc".to_string(), age: 30 },
];
let res = arr.iter().unique_by(|p| &p.name).collect::<Vec<_>>();
}
[
Person { name: "aaa", age: 10 },
Person { name: "bbb", age: 20 },
Person { name: "ccc", age: 30 }
]
My solution consuming the vector
let foo = vec![1, 2, 3, 1, 4, 1, 5];
eprintln!(
"{:?}",
foo.into_iter()
.collect::<std::collections::HashSet<u32>>()
.into_iter()
.collect::<Vec<u32>>()
);
The problem is that the output is not ordered as it was before
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