выделение объектов в векторе на основе вектора логических значений в с ++ - PullRequest
0 голосов
/ 08 марта 2019

У меня есть вектор логических значений ( например, true, true, false, false) и другой вектор того же размера, но другого типа.Я хочу выходной вектор с элементами второго вектора в соответствии с истиной в первом векторе.

По сути, я пытаюсь воспроизвести то, что в Julia или R делают:

vec = vec[to_select]

Я пытался написать copy_if, но, скажем так, компилятор не сделал 'мне это совсем не нравитсяЭто то, что у меня есть

  auto it = copy_if(vec.begin(), vec.end(), to_select.begin(), vec.begin(), [](auto& val, auto& cond){return cond;});

А затем изменить его размер:

vec.resize(std::distance(vec.begin(), it));

Любое предложение сделать это чисто и быстро, возможно, без создания нового вектора?

1 Ответ

2 голосов
/ 08 марта 2019

Векторы имеют гарантированные смежные элементы. Таким образом, здесь можно использовать идиому удаления / стирания, используя арифметику указателей для элементов при вычислении смещения в последовательности флагов удержания:

#include <vector>
#include <algorithm>
int main()
{
    std::vector<int> vec = { 1,2,3,4,5,6,7,8 };
    std::vector<bool> flags = { true, true, true, false, true, false, false, true };

    vec.erase(std::remove_if(std::begin(vec), std::end(vec),
        [&](int& arg) { return !flags[&arg - vec.data()]; }), vec.end());

    for (auto x : vec)
        std::cout << x << ' ';
    std::cout.put('\n');
}

выход

1 2 3 5 8

Очевидно, что очень важно, чтобы размеры vec и flags были одинаковыми (точнее, flags по крайней мере равен vec).

...