publicMan
publicMan

Reputation: 19

Returning vector of smaller length to an already populated Vector

I have a vector filled with x number of values, but i need to iterate a function several times using the initial vector, but returning a vector of potentially less values each time. Here's where I've got to currently, currently the vector keeps all the values and i'm not sure how to either override the initial vector declaration or remove items from that initial vector efficiently.

for (auto& image : images)
    {
        rValues.push_back(image->pixels[pix].r);
        gValues.push_back(image->pixels[pix].g);
        bValues.push_back(image->pixels[pix].b);
    }
    for (int i = 0; i < 5; i++)
    {
        float rMedian = calculateMedian(rValues);
        float rsD = calculateStandardDeviation(rValues);
        rValues = sigmaClip(rValues, rsD, rMedian);


        for (auto& r : rValues)
        {
            std::cout << "r val : " << r << "\n";
        }
        system("pause");
    }

(Ignore the std::cout of the rValues, was using this to check if values were being removed each iteration).

Then this is what I have implemented in the sigmaClip function that is the one that needs to return a vector of a different length.

std::vector<float> sigmaClip(std::vector<float> values, float sD, float median)
{
    //Sigma Clip
    float upperBound = median + sD;
    float lowerBound = median - sD;
    std::vector<float> returnVals;
    for (auto& val : values)
    {
        if ((val > lowerBound) && (val < upperBound))
            returnVals.push_back(val);
    }

    return returnVals;
}

I tried initially using .erase() and remove_if on the vector being passed into sigmaClip() but I don't think these functions worked as I intended, hence creating another vector within sigmaClip() and returning that in hopes it would override the initial rValues vector.

Upvotes: 0

Views: 196

Answers (1)

ShadowRanger
ShadowRanger

Reputation: 155363

std::remove_if should do the job just fine if paired with the erase method to effect the erase-remove idiom. Redefine sigmaClip to accept a mutable reference to values (rather than returning it), and something like:

void sigmaClip(std::vector<float>& values, float sD, float median)
{
    //Sigma Clip
    const float upperBound = median + sD;
    const float lowerBound = median - sD;
    values.erase(std::remove_if(std::begin(values), std::end(values),
                                [=](float val) { return val < lowerBound || val > upperBound; }),
                 std::end(values));
}

should work fine, changing the call site to:

// Remove assignment back to rValues
sigmaClip(rValues, rsD, rMedian);

Upvotes: 1

Related Questions