Внимание: этот ответ предоставляет решение, которое было релевантным в то время , до того, как были введены новые возможности MongoDB 2.2 и выше. См. Другие ответы, если вы используете более новую версию MongoDB.
Параметр селектора полей ограничен полными свойствами. Он не может использоваться для выбора части массива, только для всего массива. Я попытался использовать оператор $ positional , но это не сработало.
Самый простой способ - просто фильтровать фигуры на клиенте.
Если вам действительно нужен правильный вывод непосредственно из MongoDB, вы можете использовать map-reduce для фильтрации фигур.
function map() { filteredShapes = []; this.shapes.forEach(function (s) { if (s.color === "red") { filteredShapes.push(s); } }); emit(this._id, { shapes: filteredShapes }); } function reduce(key, values) { return values[0]; } res = db.test.mapReduce(map, reduce, { query: { "shapes.color": "red" } }) db[res.result].find()
AB.reserve( A.size() + B.size() ); // preallocate memory
AB.insert( AB.end(), A.begin(), A.end() );
AB.insert( AB.end(), B.begin(), B.end() );
Зависит от того, действительно ли вам нужно физически объединить два вектора или вы хотите создать конкатенацию ради итерации. Функция boost :: join
http://www.boost.org/doc/libs/1_43_0/libs/range/doc/html/range/reference/utilities/join.html
даст вам это.
std::vector<int> v0;
v0.push_back(1);
v0.push_back(2);
v0.push_back(3);
std::vector<int> v1;
v1.push_back(4);
v1.push_back(5);
v1.push_back(6);
...
BOOST_FOREACH(const int & i, boost::join(v0, v1)){
cout << i << endl;
}
должен дать вам
1
2
3
4
5
6
Примечание boost :: join не копирует два вектора в новый контейнер, но генерирует пару итераторов (диапазон), которые охватывают промежуток обоих контейнеров. Будет некоторая рабочая нагрузка, но, возможно, меньше, чем копирование всех данных в новый контейнер.
Если ваши векторы отсортированы *, проверьте set_union из & lt; algorithm & gt;.
set_union(A.begin(), A.end(), B.begin(), B.end(), AB.begin());
В ссылке
есть более подробный пример ] * thanks rlbond
На основании Ответ Кирил В. Лядвинский , я сделал новую версию. Этот фрагмент использует шаблон и перегружает. С его помощью вы можете писать vector3 = vector1 + vector2
и vector4 += vector3
. Надеюсь, это поможет.
template <typename T>
std::vector<T> operator+(const std::vector<T> &A, const std::vector<T> &B)
{
std::vector<T> AB;
AB.reserve( A.size() + B.size() ); // preallocate memory
AB.insert( AB.end(), A.begin(), A.end() ); // add A;
AB.insert( AB.end(), B.begin(), B.end() ); // add B;
return AB;
}
template <typename T>
std::vector<T> &operator+=(std::vector<T> &A, const std::vector<T> &B)
{
A.reserve( A.size() + B.size() ); // preallocate memory without erase original data
A.insert( A.end(), B.begin(), B.end() ); // add B;
return A; // here A could be named AB
}
::
принимается;)
– aloisdg
10 August 2017 в 17:36
еще один простой вариант, который не был назван струей:
copy(A.begin(),A.end(),std::back_inserter(AB));
copy(B.begin(),B.end(),std::back_inserter(AB));
и с использованием алгоритма слияния:
#include <algorithm> #include <vector> #include <iterator> #include <iostream> #include <sstream> #include <string> template<template<typename, typename...> class Container, class T> std::string toString(const Container<T>& v) { std::stringstream ss; std::copy(v.begin(), v.end(), std::ostream_iterator<T>(ss, "")); return ss.str(); }; int main() { std::vector<int> A(10); std::vector<int> B(5); //zero filled std::vector<int> AB(15); std::for_each(A.begin(), A.end(), [](int& f)->void { f = rand() % 100; }); std::cout << "before merge: " << toString(A) << "\n"; std::cout << "before merge: " << toString(B) << "\n"; merge(B.begin(),B.end(), begin(A), end(A), AB.begin(), [](int&,int&)->bool {}); std::cout << "after merge: " << toString(AB) << "\n"; return 1; }
Именно это функция-член std::vector::insert
для
std::vector<int> AB = A;
AB.insert(AB.end(), B.begin(), B.end());
insert
на итераторах с произвольным доступом и была зарезервирована вверх.
– GManNickG
5 July 2010 в 20:28
distance
имеет сложность O (1)). Тем не менее, гарантии производительности insert
- это то, о чем следует помнить, когда вы можете часто делать лучше, планируя заранее.
– Nick Bastin
5 July 2010 в 21:38
size < capacity
в большинстве случаев прогнозирование ветвлений, скорее всего, приведет к тому, что инструкции ветвления без перераспределения будут находиться в конвейере команд, минимизируя задержку, вызванную ветвлением, за исключением низкого количества итераций. Это предполагает хорошую реализацию вектора, плюс конвейер команд процессора и amp; [хороший], но это довольно надежные предположения для современной инструментальной и настольной машин. Не знаю о смартфонах, хотя ..
– boycy
24 February 2015 в 15:50
Все решения верны, но мне было проще написать функцию для ее реализации. например:
template <class T1, class T2>
void ContainerInsert(T1 t1, T2 t2)
{
t1->insert(t1->end(), t2->begin(), t2->end());
}
Таким образом вы можете избежать временного размещения следующим образом:
ContainerInsert(vec, GetSomeVector());