patterncppMinor
Find element yielding the largest value w.r.t. custom function
Viewed 0 times
theyieldingfunctionvaluelargestcustomelementfind
Problem
I made a function to find the element that yields the largest value when put into a custom functor.
I think this is missing from the STL. I can think of three ways to do this in STL:
The first two are really cumbersome and the third calls the functor twice as many times as necessary. Hence this:
Any suggestions?
I think this is missing from the STL. I can think of three ways to do this in STL:
- Transform the container by the functor. Find the maximum in the transformed version. Take the corresponding element from the original container.
- Transform the container to an iterable of
std::pairs containing the iterators to the original values and the corresponding functor result value. Write a custom comparison function which compares the.secondof the pairs. Find max among the pairs withstd::max_element. Take.firstof the resulting iterator.
- Use a custom comparator functor in
std::max_element(`return f(lhs)
The first two are really cumbersome and the third calls the functor twice as many times as necessary. Hence this:
template
auto maxElementBy(Iterable const& iterable, UnaryFun criterion)
-> decltype(std::begin(iterable))
{
typedef decltype(criterion(*std::begin(iterable))) CriterionResult;
auto itCurrent = std::begin(iterable);
auto itEnd = std::end(iterable);
if (itCurrent == itEnd)
{
return itEnd;
}
CriterionResult bestValue = criterion(*itCurrent);
auto itBest = itCurrent;
++itCurrent;
for (; itCurrent != itEnd; ++itCurrent)
{
CriterionResult currentValue = criterion(*itCurrent);
if (bestValue < currentValue)
{
itBest = itCurrent;
bestValue = std::move(currentValue);
}
}
return itBest;
}Any suggestions?
Solution
Setting aside the std::accumulate discussion, I have one recommendation. The signature
seems to be more flexible. It allows partial ranges, and seems more in line with the std design approach.
template
auto maxElementBy(Iterator first, Iterator last, UnaryFun criterion)
-> Iteratorseems to be more flexible. It allows partial ranges, and seems more in line with the std design approach.
Code Snippets
template<typename Iterator, typename UnaryFun>
auto maxElementBy(Iterator first, Iterator last, UnaryFun criterion)
-> IteratorContext
StackExchange Code Review Q#51552, answer score: 2
Revisions (0)
No revisions yet.