STL 컨테이너를 필터링하는 현대적인 방법?
수년간의 C # 이후에 C ++로 돌아와서 저는 현대가 무엇인지 궁금합니다. 읽기 : C ++ 11-배열을 필터링하는 방법, 즉이 Linq 쿼리와 유사한 것을 어떻게 얻을 수 있는지 궁금합니다.
var filteredElements = elements.Where(elm => elm.filterProperty == true);
요소 벡터를 필터링하려면 ( strings
이 질문을 위해)?
명시 적 메서드 를 정의 boost::filter_iterator
해야하는 이전 STL 스타일 알고리즘 (또는 같은 확장 )이 지금 대체 되기를 진심으로 바랍니다 .
cplusplus.com의 예를 참조하십시오 std::copy_if
.
std::vector<int> foo = {25,15,5,-5,-15};
std::vector<int> bar;
// copy only positive numbers:
std::copy_if (foo.begin(), foo.end(), std::back_inserter(bar), [](int i){return i>=0;} );
std::copy_if
foo
여기 에있는 모든 요소에 대해 람다 식을 평가하고 반환 true
하면 값을에 복사합니다 bar
.
을 std::back_inserter
사용하면 먼저 필요한 크기로 크기를 조정할 필요없이 반복자를 bar
사용하여 (사용하여 push_back()
) 끝에 새 요소를 실제로 삽입 할 수 있습니다 .
목록의 새 복사본이 실제로 필요하지 않은 경우보다 효율적인 방법은 remove_if
실제로 원래 컨테이너에서 요소를 제거하는입니다.
Boost.Range 도 언급 할 가치가 있다고 생각 합니다. 결과 코드는 원본과 매우 유사합니다.
#include <boost/range/adaptors.hpp>
// ...
using boost::adaptors::filtered;
auto filteredElements = elements | filtered([](decltype(elements)::value_type const& elm)
{ return elm.filterProperty == true; });
유일한 단점은 람다의 매개 변수 유형을 명시 적으로 선언해야한다는 것입니다. decltype (elements) :: value_type을 사용했습니다. 왜냐하면 정확한 유형을 철자 할 필요가없고 일반성을 추가하기 때문입니다. 또는 C ++ 14의 다형성 람다를 사용하여 유형을 간단히 auto로 지정할 수 있습니다.
auto filteredElements = elements | filtered([](auto const& elm)
{ return elm.filterProperty == true; });
filterElements는 순회에 적합한 범위이지만 기본적으로 원래 컨테이너의보기입니다. 기준을 충족하는 요소의 복사본으로 채워진 다른 컨테이너가 필요한 경우 (원래 컨테이너의 수명과 독립적 인) 다음과 같이 표시 될 수 있습니다.
using std::back_inserter; using boost::copy; using boost::adaptors::filtered;
decltype(elements) filteredElements;
copy(elements | filtered([](decltype(elements)::value_type const& elm)
{ return elm.filterProperty == true; }), back_inserter(filteredElements));
C #과 동등한 C ++ 제안
var filteredElements = elements.Where(elm => elm.filterProperty == true);
필터링을 수행하기 위해 람다 조건자를 전달하는 템플릿 함수를 정의합니다. 템플릿 함수는 필터링 된 결과를 반환합니다. 예 :
template<typename T>
vector<T> select_T(vector<T> inVec, function<bool(const T&)> predicate)
{
vector<T> result;
copy_if(inVec.begin(), inVec.end(), back_inserter(result), predicate);
return result;
}
사용하기-간단한 예를 제공합니다.
std::vector<int> mVec = {1,4,7,8,9,0};
// filter out values > 5
auto gtFive = select_T<int>(mVec, [](auto a) {return (a > 5); });
// or > target
int target = 5;
auto gt = select_T<int>(mVec, [target](auto a) {return (a > target); });
underscore-d 제안에 따라 개선 된 pjm 코드 :
template <typename Cont, typename Pred>
Cont filter(const Cont &container, Pred predicate) {
Cont result;
std::copy_if(container.begin(), container.end(), std::back_inserter(result), predicate);
return result;
}
용법:
std::vector<int> myVec = {1,4,7,8,9,0};
auto filteredVec = filter(myVec, [](int a) { return a > 5; });
C ++ 20에서는 범위 라이브러리의 필터보기를 사용합니다.
vec | view::filter([](int a){ return a % 2 == 0; })
에서 짝수 요소를 lazily 반환합니다 vec
.
( [range.adaptor.object] / 4 및 [range.filter] 참조 )
참고URL : https://stackoverflow.com/questions/21204676/modern-way-to-filter-stl-container
'Programing' 카테고리의 다른 글
Ubuntu 10.10 (Maverick Meerkat)에 Sun Java JDK를 설치하는 방법은 무엇입니까? (0) | 2020.11.20 |
---|---|
문자열이 문자열로 시작하는지 테스트 하시겠습니까? (0) | 2020.11.20 |
JAX-RS 웹 서비스에서 교차 도메인 요청을 사용하는 방법은 무엇입니까? (0) | 2020.11.20 |
Jupyter 내 Tensorflow 세트 CUDA_VISIBLE_DEVICES (0) | 2020.11.20 |
Query if Android database exists! (0) | 2020.11.19 |