C++ - Developing own version of std::count_if

For a task, I'm doing some simple data sampling to determine which samples contains audio counting the total number of energy. I've been looking into the std::count_if function, and, although this suits my needs to a certain extent, for example:

int foo = std::count_if(
               std::begin(samples), 
               std::end(samples),
               containsSound);

This counts the total number of samples that contain sound, but does not give an indication to the samples that contain sound. I came up with this solution:

std::vector<std::string> sound_files = myLib::count_sample_if(
                                              std::begin(samples),
                                              std::end(samples),
                                              samples.DirName, 
                                              containsSOund);

This would then store and push the samples.DirName to a vector which I can then use to only store the sample set of my choice.

My question is whether or not this would be easy to implement?

Answers


If you just need readability / speed of development and you don't care about performance then you can easily use std::copy_if and std::transform to obtain what you need:

std::vector<Song> songs;
std::vector<Song> filtered;
std::vector<std::string> transformed;

std::copy_if(songs.begin(), songs.end(), filtered.begin(), [](const Song &song) { return whatever you need; });
std::transform(filtered.begin(), filtered.end(), transformed.begin(), [](const Song &song) { return song.sample; });

Or you could use std::for_each:

std::vector<Song> songs;
std::vector<std::string> transformed;

std::for_each(songs.begin(), songs.end(), [&](const Song &song) { if (song.containsSample()) transformed.push_back(song.sample); });

Then the amount of samples that contains sound is just transformed.size().


If I have understood correctly the simplest way is to use standard algorithm std::copy_if. There is no need to count elements because you can simply get it by using another standard function std::distance. For example let assume that you have an array of integers and want to count positive values and at the same time to copy them in a vector. The code could look the following way

int a[] = { 1, -3, -5, 9, 2, -4, -1, -7, 5, 8 };

std::vector<int> v;

std::copy_if( std::begin( a ), std::end( a ), 
              std::back_inserter( v ), 
              std::bind2nd( std::greater<int>(), 0 ) );

std::cout << "The number of positive elements is " << std::distance( v.begin(), v.end() ) << std::endl;

It would be very easy to implement - additionally, there is no need to implement it. You can write a functor (aka function object) or lambda expression to do the comparison and hold the vector for you, which would allow you to continue to use std::count_if (or one of the other standard algorithms).

std::vector<std::string> mySongs;
std::string myDirectory = "C:/";
std::copy_if(std::begin(samples), std::end(samples), std::back_inserter(mySongs), [](const std::string& s)
{
    // return true or false based on some criteria here
}); 
std::transform(std::begin(mySongs), std::end(mySongs), std::begin(mySongs), [](const std::string& s)
{
    return myDirectory + s;
});

here is the implementation of count_if, all you need to do is to create a vector, push back the result if it is acceptable, and return the vector after you finish looping through the range.


Need Your Help

Show hidden image with jQuery

javascript jquery html css

FYI: I am learning how to code with an online tutorial. In this tutorial, we are learning javascript and jQuery. The point is to:

AngularJS Directive - How can I tell if attribute's expression is fully evaluated?

angularjs

Say I have a directive that accepts an attribute named "url" that could be made up of expressions and static texts, and the evaluated result of "url" will be used as the url of a ng-include in the