0

표준 C++ lib에서 map 기능을 찾지 못해서 놀랐습니다. 아래라고으로,이 기능을 필터링하는 것 : 지금은이 솔루션매핑 기능의 C++ 아날로그

template <typename Container, typename InputIterator, typename UnaryPredicate> 
Container filter(InputIterator _from, InputIterator _to, UnaryPredicate _pred) 
{ 
    Container collection; 
    return std::accumulate(_from, _to, collection, 
     [_pred] (Container acc, const InputIterator::value_type & val) -> Container 
     { 
      if (_pred(val)) 
       acc.insert(std::end(acc), val); 
      return acc; 
     }); 
} 

////////////////////////////// 
// usage 

    std::vector<int> vec = {0, 1, 2, 3}; 
    std::vector<int> newVec = filter<decltype(newVec)>(std::begin(vec), std::end(vec), 
     [] (int n) 
     { 
      return n % 2 == 0; 
     }); 

하지만 어쩌면 좀 더 일반적인 솔루션


편집 존재를 사용하고 있습니다. 좋아, 내 map 구현 : 그들은 소스 컬렉션을 변경 std::transform

template <typename T, typename MapFunction> 
T map(T source, MapFunction func) 
{ 
    T collection; 
    for (auto val : source) 
    { 
     collection.insert(std::end(collection), func(val)); 
    } 
    return collection; 
} 

그래서 문제 등,하지만 그들은 다른 하나를 반환해야합니다.

+4

왜 '필터'에 대한 구현을 보여 주면서'map' 함수에 대해 묻고 있습니까? – juanchopanza

+1

C++에는 각 요소의 함수를 호출하기위한'std :: for_each'가 있습니다. – chris

+0

@juanchopanza 필터는 단지 술어가있는지도 일뿐입니다. 오해 미안 해요, 나 둘 다 거의 동일합니다. –

답변

2

map (예 파이썬 내장)에 가장 가까운 std::for_each 또는 std::transform, 반복자 쌍에 의해 정의되는 범위에 함수를 적용하는 것이다 : (A)에 적절한 변형을 위해,

예에서 en.cppreference.com :

int main() 
{ 
    std::string s("hello"); 
    std::transform(s.begin(), s.end(), s.begin(), std::ptr_fun<int, int>(std::toupper)); 
    std::cout << s; 
} 

또는 람다 함수와 for_each, 여기서 우리는 (1)에 의해 각각의 요소를 증가 :

int main() 
{ 
    std::vector<int> nums{3, 4, 2, 9, 15, 267}; 
    std::for_each(nums.begin(), nums.end(), [](int &n){ n++; }); 
} 

<algorithm> 헤더 부분.

+0

'toupper'를 사용하는 경우, 인자가 unsigned char (또는 적어도 하나의 범위)인지 확인해야합니다. "Hello"는 모호한 문자 세트가 아니라면 모두 허용됩니다. 그러나 일반적으로 허용되지는 않습니다. – chris

+0

@chris : 어쨌든'toupper'는 대부분의 지역에 적합하지 않습니다. – Deduplicator