вы можете использовать следующую вспомогательную функцию:
function content(divSelector, value) {
document.querySelector(divSelector).innerHTML = value;
}
content('#content',"whatever");
Где #content
должен быть прав Селектор CSS
Дополнительно - сегодня (2018.07.01) Я сделал сравнение скорости для jQuery и чистых js-решений (MacOs High Sierra 10.13.3 на Chrome 67.0.3396.99 (64-разрядная версия) , Safari 11.0.3 (13604.5.6), Firefox 59.0.2 (64-разрядная версия)):
document.getElementById("content").innerHTML = "whatever"; // pure JS
$('#content').html('whatever'); // jQuery
Решение jquery было медленнее, чем чистое решение js: 69% на firefox, 61% на сафари, 56% на хром. Самый быстрый браузер для чистых js был firefox с 560M операций в секунду, второй - сафари 426M, а самым медленным был хром 122M.
Итак, победители - это чистые js и firefox (в 3 раза быстрее, чем хром!)
Вы можете проверить его на своем компьютере: https://jsperf.com/js-jquery-html-content-change
Если вы используете C ++ 11 и хотите переместить элементы, а не просто их копировать, вы можете использовать std :: move_iterator ( http://en.cppreference.com/w/cpp/iterator / move_iterator ) вместе со вставкой (или копией):
#include <vector>
#include <iostream>
#include <iterator>
int main(int argc, char** argv) {
std::vector<int> dest{1,2,3,4,5};
std::vector<int> src{6,7,8,9,10};
// Move elements from src to dest.
// src is left in undefined but safe-to-destruct state.
dest.insert(
dest.end(),
std::make_move_iterator(src.begin()),
std::make_move_iterator(src.end())
);
// Print out concatenated vector.
std::copy(
dest.begin(),
dest.end(),
std::ostream_iterator<int>(std::cout, "\n")
);
return 0;
}
Это не будет более эффективным для примера с int, поскольку перемещение их неэффективно, чем копирование, но для структура данных с оптимизированными ходами, она может избежать копирования ненужного состояния:
#include <vector>
#include <iostream>
#include <iterator>
int main(int argc, char** argv) {
std::vector<std::vector<int>> dest{{1,2,3,4,5}, {3,4}};
std::vector<std::vector<int>> src{{6,7,8,9,10}};
// Move elements from src to dest.
// src is left in undefined but safe-to-destruct state.
dest.insert(
dest.end(),
std::make_move_iterator(src.begin()),
std::make_move_iterator(src.end())
);
return 0;
}
После перемещения элемент src остается в неопределенном, но безопасном для разрушения состоянии, а его прежние элементы были переданы напрямую к новому элементу dest в конце.
Если вы заинтересованы в надежной гарантии исключения (когда конструктор копирования может генерировать исключение):
template<typename T>
inline void append_copy(std::vector<T>& v1, const std::vector<T>& v2)
{
const auto orig_v1_size = v1.size();
v1.reserve(orig_v1_size + v2.size());
try
{
v1.insert(v1.end(), v2.begin(), v2.end());
}
catch(...)
{
v1.erase(v1.begin() + orig_v1_size, v1.end());
throw;
}
}
Аналогичный append_move
с сильной гарантией не может быть реализован вообще, если конструктор перемещения векторного элемента может бросить (что маловероятно, но все же).
insert
уже справляется с этим. Кроме того, этот вызов erase
эквивалентен resize
.
– Potatoswatter
27 December 2016 в 08:02
Вы должны использовать vector :: insert
v1.insert(v1.end(), v2.begin(), v2.end());
Если то, что вы ищете, это способ добавить вектор к другому после создания, vector::insert
- ваш лучший выбор, как было сказано несколько раз, например:
vector<int> first = {13};
const vector<int> second = {42};
first.insert(first.end(), second.cbegin(), second.cend());
К сожалению, нет способа построить const vector<int>
, как указано выше, вы должны построить, а затем insert
.
Если то, что вы действительно ищете, является контейнером чтобы удерживать конкатенацию этих двух vector<int>
s, может быть что-то более доступное для вас, если:
vector
содержит примитивы const
Если все это верно, я бы предложил использовать basic_string
, который char_type
соответствует размеру примитива, содержащегося в вашем vector
. Вы должны включить в свой код static_assert
, чтобы подтвердить, что эти размеры остаются неизменными:
static_assert(sizeof(char32_t) == sizeof(int));
С этим удерживанием true вы можете просто сделать:
const u32string concatenation = u32string(first.cbegin(), first.cend()) + u32string(second.cbegin(), second.cend());
Для получения дополнительной информации о различиях между string
и vector
вы можете посмотреть здесь: https://stackoverflow.com/a/35558008/2642059
Для живой пример этого кода вы можете посмотреть здесь: http://ideone.com/7Iww3I
Вот общее решение с использованием семантики перемещения C ++ 11:
template <typename T>
std::vector<T> concat(const std::vector<T>& lhs, const std::vector<T>& rhs)
{
if (lhs.empty()) return rhs;
if (rhs.empty()) return lhs;
std::vector<T> result {};
result.reserve(lhs.size() + rhs.size());
result.insert(result.cend(), lhs.cbegin(), lhs.cend());
result.insert(result.cend(), rhs.cbegin(), rhs.cend());
return result;
}
template <typename T>
std::vector<T> concat(std::vector<T>&& lhs, const std::vector<T>& rhs)
{
lhs.insert(lhs.cend(), rhs.cbegin(), rhs.cend());
return std::move(lhs);
}
template <typename T>
std::vector<T> concat(const std::vector<T>& lhs, std::vector<T>&& rhs)
{
rhs.insert(rhs.cbegin(), lhs.cbegin(), lhs.cend());
return std::move(rhs);
}
template <typename T>
std::vector<T> concat(std::vector<T>&& lhs, std::vector<T>&& rhs)
{
if (lhs.empty()) return std::move(rhs);
lhs.insert(lhs.cend(), std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end()));
return std::move(lhs);
}
Обратите внимание, что это отличается от append
до vector
.
С C ++ 11 я предпочел бы добавить вектор b к a:
std::move(b.begin(), b.end(), std::back_inserter(a));
, когда a
и b
не перекрываются, а b
не идет которые будут использоваться больше.
insert
способу, который безопаснее.
– Deqing
1 February 2016 в 04:31
vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2 = {11, 12, 13, 14, 15};
copy(v2.begin(), v2.end(), back_inserter(v1));
std::vector<int> first;
std::vector<int> second;
first.insert(first.end(), second.begin(), second.end());
Я бы использовал функцию insert , что-то вроде:
vector<int> a, b;
//fill with data
b.insert(b.end(), a.begin(), a.end());
vector1.insert( vector1.end(), vector2.begin(), vector2.end() );
reserve
на векторе назначения?
– Faheem Mitha
5 February 2012 в 01:07
vector1.capacity() >= 2 * vector1.size()
. Что является нетипичным, если вы не вызвали std::vector::reserve()
. В противном случае вектор перераспределит, аннулирует итераторы, переданные как параметры 2 и 3.
– Drew Dormann
21 June 2012 в 21:30
.concat
или +=
или что-то
– nmr
14 October 2016 в 23:32
Или вы можете использовать:
std::copy(source.begin(), source.end(), std::back_inserter(destination));
Этот шаблон полезен, если два вектора не содержат точно такого же типа, потому что вы можете использовать что-то вместо std :: back_inserter для преобразования от одного типа к другому.
reserve
. Иногда полезно использовать std::copy
, если вы хотите использовать что-то другое, кроме back_inserter
.
– Roger Lipscombe
22 March 2010 в 19:36
Я предпочитаю тот, который уже упоминался:
a.insert(a.end(), b.begin(), b.end());
Но если вы используете C ++ 11, существует еще один общий способ:
a.insert(std::end(a), std::begin(b), std::end(b));
Кроме того, это не вопрос, но рекомендуется использовать reserve
перед добавлением для повышения производительности. И если вы конкатенируете вектор с собой, не оставляя его, он всегда должен reserve
.
Итак, в основном, что вам нужно:
template <typename T>
void Append(std::vector<T>& a, const std::vector<T>& b)
{
a.reserve(a.size() + b.size());
a.insert(a.end(), b.begin(), b.end());
}
std::
выводится через зависимый от аргумента поиск . end(a)
будет достаточно.
– Asu
13 October 2016 в 20:02
std::
, если тип a
исходит от std
, который побеждает общий аспект.
– Potatoswatter
27 December 2016 в 07:59
Добавьте этот файл в файл заголовка:
template <typename T> vector<T> concat(vector<T> &a, vector<T> &b) {
vector<T> ret = vector<T>();
copy(a.begin(), a.end(), back_inserter(ret));
copy(b.begin(), b.end(), back_inserter(ret));
return ret;
}
и используйте его следующим образом:
vector<int> a = vector<int>();
vector<int> b = vector<int>();
a.push_back(1);
a.push_back(2);
b.push_back(62);
vector<int> r = concat(a, b);
r будет содержать [1,2,62]
Честно говоря, вы могли бы быстро объединить два вектора путем копирования элементов из двух векторов в другой или просто добавить один из двух векторов !.
Метод 1: Назначить новый вектор с его размером представляет собой сумму двух исходных размеров векторов.
vector<int> concat_vector = vector<int>();
concat_vector.setcapacity(vector_A.size() + vector_B.size());
// Loop for copy elements in two vectors into concat_vector
Способ 2: добавить вектор A, добавив / вставка элементов вектора B.
// Loop for insert elements of vector_B into vector_A with insert()
function: vector_A.insert(vector_A .end(), vector_B.cbegin(), vector_B.cend());
std::move_iterator
, чтобы элементы перемещались вместо копирования. (см. ru.cppreference.com/w/cpp/iterator/move_iterator ).
– tmlen
23 February 2018 в 16:36
Общий прирост производительности для конкатенации - проверка размера векторов. И объедините / вставьте меньший с большим.
//vector<int> v1,v2;
if(v1.size()>v2.size()){
v1.insert(v1.end(),v2.begin(),v2.end());
}else{
v1.insert(v2.end(),v1.begin(),v1.end());
}
Вы можете подготовить свой собственный шаблон для оператора +:
template <typename T>
inline T operator+(const T & a, const T & b)
{
T res = a;
res.insert(res.end(), b.begin(), b.end());
return res;
}
. Следующее - просто используйте +:
vector<int> a{1, 2, 3, 4};
vector<int> b{5, 6, 7, 8};
for (auto x: a + b)
cout << x << " ";
cout << endl;
В этом примере приведены результаты:
1 2 3 4 5 6 7 8