Rust 如何根据其中一个向量中的值对两个向量共同排序?

Rust 如何根据其中一个向量中的值对两个向量共同排序?,rust,Rust,我有两个Vecs,它们对应于一个特征向量列表及其对应的类标签,我想按类标签对它们进行联合排序 然而,Rust的sort_by操作在一个切片上,而不是一个特性(或类似特性)上的通用函数,并且闭包只获取要比较的元素,而不是索引,因此我可以偷偷地将排序修改为并行 我已经考虑了解决方案: let mut both = data.iter().zip(labels.iter()).collect(); both.sort_by( blah blah ); // Now split them back in

我有两个
Vec
s,它们对应于一个特征向量列表及其对应的类标签,我想按类标签对它们进行联合排序

然而,Rust的
sort_by
操作在一个切片上,而不是一个特性(或类似特性)上的通用函数,并且闭包只获取要比较的元素,而不是索引,因此我可以偷偷地将排序修改为并行

我已经考虑了解决方案:

let mut both = data.iter().zip(labels.iter()).collect();
both.sort_by( blah blah );
// Now split them back into two vectors
我不希望每次都分配一个全新的向量来执行此操作,因为数据的大小可能非常大

当然,我总是可以实现我自己的排序,但是如果有一种内置的方法来实现它,那就更好了。

我刚刚写了一篇文章,允许您这样做:)

它可能会在将来的单个函数调用中支持这一点。

我刚刚写了一篇文章,允许您这样做:)


它很可能在将来的单个函数调用中支持这一点。

@Shepmaster我将它传递到libsvm,这要求它们是分开的,很不幸,是的。最小化分配的一种方法是只分配一个索引向量(如果元素少于40亿,它们只需要是
u32
,因此每个元素4个字节)并通过
sort\u by
索引将其排序到
标签中
。然后可以使用结果将
数据
标签
按正确顺序排列。(不幸的是,仍然分配O(n)内存。)由于
sort\u by
本身不起作用,您需要自己实现排序,可能需要使用
sort\u by
作为基础。哦,它不能仅仅给出指数,因为它们不是常数。如果您真的坚持使用
sort\u by
,那么您需要进行指针比较,以获得切片中元素的索引,然后找出
sort\u by
将对您的响应做什么,并自己对另一个向量做,这将是一种非常疯狂和脆弱的做法。所以,是的,只要看看
sort\u by
做了什么并复制它。注意
sort\u by
已经分配了2n个空间,所以除非您使用不同的排序函数,否则您不会避免分配。
[T]::sort/sort\u by
是一种稳定的排序。如果您需要一个非稳定的非分配排序,clarates.io上还有其他选择。@Shepmaster我正在将其传递给libsvm,这要求它们是分开的,所以很遗憾,是的。最小化分配的一种方法是只分配一个索引向量(如果少于40亿个元素,它们只需要是
u32
,每个元素4个字节)并通过
sort\u by
索引到
标签中进行排序。然后可以使用结果将
数据和
标签按正确顺序排列。(当然,不幸的是仍然分配了O(n)内存。)由于
sort\u by
本身无法实现排序,您需要自己实现排序,可能需要使用
sort\u by
作为基础。哦,它不能只给您索引,因为它们不是常量。如果您真的要坚持使用
sort\u by
,您需要进行指针比较以获得元素的索引在切片中输入ent,然后找出
sort\u by
与您的响应有什么关系,然后自己对另一个向量进行处理,这将是一种非常疯狂和脆弱的处理方式。因此,是的,只需看看
sort\u by
做了什么,然后复制它。注意
sort\u by
已经分配了2n个空间,因此您无法避免分配,除非您使用不同的排序功能。
[T]::sort/sort_by
是一种稳定的排序。如果您需要非稳定的非分配排序,crates.io上还有其他选择。感谢您为Rust社区做出的贡献。就我而言,这是一个遗憾,因为它是根据GPL而不是MIT/Apache授权的,与大多数Rust库一样。我已将许可证更新为Ap下的双重授权ache/MIT,就像Rust一样。感谢您对Rust社区的贡献。就我而言,这是一个遗憾,因为它是在GPL下授权的,而不是像大多数Rust库一样在MIT/Apache下授权的。我已经将许可证更新为在Apache/MIT下双重授权的,就像Rust一样。
let names = vec!["Bob", "Steve", "Jane"];
let salary = vec![10, 5, 15];
let permutation = permutation::sort(&salary[..]);
let ordered_names = permutation.apply_slice(&names[..]);
let ordered_salaries = permutation.apply_slice(&salary[..]);
assert!(ordered_names == vec!["Steve", "Bob", "Jane"]);
assert!(ordered_salaries == vec![5, 10, 15]);