Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient way to construct an array taking elements with given indexes from another array in C++

Is it possible to create an array from two other arrays, one being the source array and the second one containing the indices of elements to be taken, in C++, using only one command, without cycles, for example, using STL or boost? For example, given

double X[10] = [10., 9., 8., 7., 6., 5., 4., 3., 2., 1.];

and

int n[4] =  [0, 1, 3, 9];

I would want to have

double X[4] = [10., 9., 7., 1.]

as the result. In MATLAB, I would simply write something like X(n).

like image 559
G-s Avatar asked Dec 26 '22 18:12

G-s


2 Answers

Using c++11-features you could do it like this:

  std::vector<double> vec;
  std::transform(std::begin(n), std::end(n), std::back_inserter(vec), [&](int idx)
  {
    return x[idx];
  });

Without c++11, it could look like this:

template <typename T, std::size_t N>
struct Get_Idx
{
  Get_Idx(T (&t)[N]) : m_t(t) { }

  T (&m_t)[N];

  T operator()(std::size_t i) const
  {
    return m_t[i];
  }
};

template <typename T, std::size_t N>
Get_Idx<T, N> get_idx(T (&t) [N])
{
  return Get_Idx<T, N>(t);
}

  std::vector<double> vec2;
  std::transform(n, n + 4, std::back_inserter(vec2), get_idx(x));

Besides, why are you using c-arrays instead of STL-containers?

like image 187
MadScientist Avatar answered Jan 17 '23 16:01

MadScientist


Assuming you use std-containers and C++11 (sorry, not tested):

std::transform(n.begin(), n.end(), std::back_inserter(Y), [&X](int i) { return X[i]});
X = std::move(Y);
like image 39
stefaanv Avatar answered Jan 17 '23 16:01

stefaanv