Rust 如何根据锈迹中不连续的Vec元素进行分组?
我有一个Rust 如何根据锈迹中不连续的Vec元素进行分组?,rust,Rust,我有一个Vec,我想按a分组,但不仅仅是连续的,而是Vec中的所有元素。我发现的最接近的东西是只对连续值起作用的。我知道连续性与优化分配有关,但我只想要一个常规的C#group by。优先考虑的是不必为此而使用新的库 A不可散列,仅Ord。我想要一个生成的Vec假设“comparable”表示a:Ord,即a上有一个总的排序,您可以将(a,B)类型的项上的迭代器折叠成aB从a到Vec: 使用std::collections::BTreeMap; fn组_对(v:I)->BTreeMap 哪里 A
Vec
,我想按a
分组,但不仅仅是连续的,而是Vec
中的所有元素。我发现的最接近的东西是只对连续值起作用的。我知道连续性与优化分配有关,但我只想要一个常规的C#group by。优先考虑的是不必为此而使用新的库
A
不可散列,仅Ord
。我想要一个生成的Vec假设“comparable”表示a:Ord
,即a
上有一个总的排序,您可以将(a,B)
类型的项上的迭代器折叠成aB从a
到Vec
:
使用std::collections::BTreeMap;
fn组_对(v:I)->BTreeMap
哪里
A:Ord,
I:迭代器,
{
v、 折叠(BTreeMap::new(),| mut acc,(a,b)|{
acc.entry(a)或_default()推送(b);
行政协调会
})
}
有些人更喜欢for loop而不是fold:
fn group_pairs<A, B, I>(v: I) -> BTreeMap<A, Vec<B>>
where
A: Ord,
I: IntoIterator<Item = (A, B)>,
{
let mut result = BTreeMap::<A, Vec<B>>::new();
for (a, b) in v {
result.entry(a).or_default().push(b);
}
result
}
fn组对(v:I)->BTreeMap
哪里
A:Ord,
I:迭代器,
{
让mut result=BTreeMap:::new();
对于v中的(a,b){
结果.entry(a).或_default().push(b);
}
后果
}
例如:
let data = vec![(1, 2), (2, 3), (1, 1), (2, 4), (3, 5)];
let grouped = vec![(1, vec![2, 1]), (2, vec![3, 4]), (3, vec![5])];
assert_eq!(group_pairs(data).into_iter().collect::<Vec<_>>(), grouped);
let data=vec![(1, 2), (2, 3), (1, 1), (2, 4), (3, 5)];
让我们来看看![(1,vec![2,1]),(2,vec![3,4]),(3,vec![5]);
断言!(将对(数据)分组到iter()。收集::(),分组);
另外,A
保证具有哪些特征实现?如果它有Hash
,那么这可以通过折叠到HashMap
上轻松完成。相关:不需要计数,只需附加到向量。如果a:Ord
,你也可以使用BTreeMap
而不是HashMap
。“compariable”是指a:Eq
,a:Ord
,A:PartialEq
或A:PartialOrd
?@ditoslav嘿,慢点!我真的没有恶意——只是这些差异对解决方案很重要。我已经为A:Ord
的案例提供了答案,但是如果您只有A:PartialOrd
,这对您来说将是无用的。关于“你不能假设我想要或[d]”,这正是我在回答的第一句话中所做的。我想要一个结果VecSee
let data = vec![(1, 2), (2, 3), (1, 1), (2, 4), (3, 5)];
let grouped = vec![(1, vec![2, 1]), (2, vec![3, 4]), (3, vec![5])];
assert_eq!(group_pairs(data).into_iter().collect::<Vec<_>>(), grouped);