# Sort struct-of-array format with RVec

I am using RDataFrame, and I have `RVec`s containing various jet variables. I need to work with the 4 highest pT jets, so I need to sort these by the jet pT. How can I do this easily (preferably without having to define a new column containing vectors of structs)?

ROOT Version: 6.14
Platform: LCG dev4

You may try using something like std::nth_element, to avoid sorting the whole vector. Here is an example:

``````#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

int main()
{
std::vector<int> v{5, 6, 4, 3, 22, 15, 7, 9, 3};
std::nth_element(v.begin(), v.begin()+4, v.end(), std::greater<int>());
std::cout << "The four largest elements are "
<< v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << '\n';
return 0;
}
``````

This program gives me the following output:

``````The four largest elements are 9, 22, 15, 7
``````

It’s not that sorting is inefficient, it’s that I have to rearrange the other vectors according to the order the pT vector got sorted.

I haven’t found anything in either the standard library or range-v3 that would easily help. The best solution I have now is to use range-v3’s zipWith to turn it into a vector of structs, then sort that.

It’s not that sorting is inefficient, it’s that I have to rearrange the other vectors according to the order the pT vector got sorted.

In that case you can use `std::sort` with a custom function to get the indices in the order you want, then you can just apply the sorting to the other vectors.

Maybe this example will help a bit:

``````#include <algorithm>
#include <numeric>
#include <iostream>
#include <vector>

template<typename T>
inline std::vector<size_t> index_sort(const std::vector<T> &v)
{
std::vector<size_t> idx(v.size());
std::iota(idx.begin(), idx.end(), size_t{});
std::sort(idx.begin(), idx.end(), [&v](const size_t& i, const size_t& j) { return v[i] < v[j]; });
return idx;
}

template<typename T>
void permute(std::vector<T>& v, std::vector<typename std::vector<T>::size_type>&& idx)
{
std::vector<T> tmp = v;
auto it = v.begin();
for (auto& i : idx)
*it++ = tmp[i];
}

int main()
{
std::vector<int> v = {9, 6, 3, 5, 2, 4, 1, 8, 7, 0};

permute(v, index_sort(v));

for (auto i : v)
std::cout << i << " ";
std::cout << std::endl;

return 0;
}
``````

It gives the following output:

``````0 1 2 3 4 5 6 7 8 9
``````

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.