-1

Edit: I appreciate the answers very much!

So imagine we have a struct like this

struct BadQuestion
{
   float a;
   float b;

} BadArray[10];

On a typical day float a will look like following

{ 0, 152.52, 25.26, 5.166, 263.25, 256.256, 452.25, 0, 0, 0 }

Now I need to find the smallest value (5.166) and get the index of that in the array (which would be 3) because later I will need to extract float b from BadArray[3].

I do not want to include the 0 values in the search, of course. And what I've tired is adding all non-0 values to a vector then use min_element to get the lowest value of float a. Problem is that I don't know how to get the index.

Current code

vector<float> temp;
int size = 0;
for (int i = 0; i < 10; i++)
{
    if (BadArray[i].a != 0) {
        temp.push_back(BadArray[i].a);
        size++;
    }
}

auto entity = min_element(temp.begin(), temp.end());
Zute
  • 49
  • 8
  • Please post the code that you have now, otherwise your question is quite unclear. – Anton Savin Dec 15 '14 at 01:01
  • possible duplicate of [Best way to get the index of an iterator?](http://stackoverflow.com/questions/2152986/best-way-to-get-the-index-of-an-iterator) – OldProgrammer Dec 15 '14 at 01:03

4 Answers4

2
float lowestvalue = FLT_MAX; //float max
int index = -1;
for(int i = 0; i < 10; i++)
{
     if(BadQuestion[i].a < lowestvalue && BadQuestion[i].a != 0)
     {
         lowestvalue = BadQuestion[i].a;
         index = i;
     }
}

float patato = BadQuestion[index].b;
Thellimist
  • 3,757
  • 5
  • 31
  • 49
0

So use a custom comparator! Here's a fairly lengthy one:

#include <array>
#include <iostream>

int main() {
    std::array<float, 10> arr = {0, 152.52, 25.26, 5.166, 263.25, 256.256, 452.25, 0, 0, 0};

    auto it = std::min_element(begin(arr), end(arr), [](float lhs, float rhs) -> bool {
        if (lhs == rhs)
            return false;
        if (lhs == 0)
            return false;
        if (rhs == 0)
            return true;
        return lhs < rhs;
    });

    std::cout << std::distance(begin(arr), it) << "\n";
}

Output:

3

We could also perform this work on BadQuestion:

struct BadQuestion {
    float a;
    float b;
};

int main() {
    std::array<struct BadQuestion, 3> arr;

    arr[0] = {12, 3};
    arr[1] = {0, 17};
    arr[2] = {9, 14};

    auto it = std::min_element(begin(arr), end(arr), [](BadQuestion const & lhs, BadQuestion const & rhs) -> bool {
        if (lhs.a == rhs.a)
            return false;
        if (lhs.a == 0)
            return false;
        if (rhs.a == 0)
            return true;
        return lhs.a < rhs.a;
    });

    std::cout << std::distance(begin(arr), it) << "\n";
    std::cout << it->b << "\n";
}
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • Hello! Can you explain why this would make a better solution than @Furkan's answer? His seems to work well and it dodges the use of an additional vector. – Zute Dec 15 '14 at 01:09
  • @Zute: I'm fine with either answer. This code (also) doesn't use an additional vector. You could also easily take this comparator and apply it to a sort, which you couldn't easily do with Furkan's answer. – Bill Lynch Dec 15 '14 at 01:13
  • @Zute: And to perhaps explain the comparator, all it is doing is performing `std::less`, but it makes sure that `0` is considered the largest value. – Bill Lynch Dec 15 '14 at 01:16
0

I'm not sure I understand your question fully but here goes

#include <limits>
float min = numeric_limits<float>::max();
int minIndex = 0;
for (int i = 0; i < (sizeof(BadArray) / sizeof(BadArray[0])); i++) {
    if ((BadArray[i].a > 0) && (BadArray[i].a < min)) {
        min = BadArray[i].a;
        minIndex = i;
    }
}
user3400223
  • 748
  • 5
  • 10
0

Here's a fun way to do it that's totally different from the other examples: let's use Boost.Ranges:

float arr[] = { 0, 152.52, 25.26, 5.166, 263.25, 256.256, 452.25, 0, 0, 0 };

auto it = boost::min_element(
    arr | boost::adaptors::filtered(non_zero{}));

With:

struct non_zero {
    bool operator()(float f) { return f != 0.0; }
};

At that point, *it == 5.166 and (&*it - arr) == 3 is your index. min_element also takes a comparator if you want it to work on your structs, so your non_zero will have to change to take that into account too, but the structure looks the same: basically this lets us separate the min_element part from the filtered part, which is quite nice.

Barry
  • 286,269
  • 29
  • 621
  • 977