Returning a minimum value and index from an array

I am new to the forum and still learning about the programming side of things, Im getting better each day but I still have a massive amount to learn.

I am currently making a GPS display which will also incorporate an AutoPilot Function for my Boat.
Maybe a bit complicated for my skill level but I love a challenge :slight_smile:

I am making really good progress but im having difficulty with the following -

I am calculating distances to waypoints and then calculating which one is closest,
I have a sample code which includes an array of distances.
I can return the lowest value with the following sample code but i would also like to return the coresponding index of that value.

eg, "The closest waypoint is 13 meteres away"
"The closest waypoint is waypoint.....WP6" // Its the waypont number I would like help with

Hopefully this all makes sense, I can provide my full code on request if its needed.

I will most likely kick myself when i find out how its done >:(

void setup() {
  Serial.begin(9600);
 
}

void loop() {
  
 int WP1 = 43;
 int WP2 = 22;
 int WP3 = 234;
 int WP4 = 878;
 int WP5 = 678;
 int WP6 = 13;
 int WP7 = 654;
 
  int array[] = {WP1, WP2, WP3, WP4, WP5, WP6, WP7};
  int count = sizeof(array) / sizeof(array[0]);
  int index = 0 ;               

  for (int i = 1; i < count; i++)
  {
    if (array[i] < array[index]) {
      index = i;
    }
  }
  Serial.print("Total Number Of WayPoints = ");
  Serial.println(count);
  Serial.print("Closest WayPoint is ");
  Serial.print(array[index]);
  Serial.println(" Meters Away");
  Serial.println();
  delay(2000);
  

  
}

Google it and kick yourself. Just use the thread title.

Another way to look at your issue:

If you have the index into the array where the lowest value is, why do you need the function to also return the lowest value.

In any case, the answer is "pass by reference". In case you don't recognize it as such, that's a google search phrase.

I am already starting to kick myself :confused:

I need the index returned to me so I can use it in another part of my sketch to navigate with the AutoPilot to the closest waypoint.

It seems when I return the value of index (+1) i get the required WP number , which in the following example is 7 (WP7)

I am going to google my own thread title and kick myself :slight_smile: (I was searching google prior to my post but I couldnt see anything that made sense to my pea size brain :confused: )

I will also search for "pass by reference" and do some more homework.
Even although the following example 'seems' to work, I want to understand it better before I use it in my main sketch.

Thank you for the guidance.

void setup() {
  Serial.begin(9600);
 
}

void loop() {
  
 int WP1 = 43;
 int WP2 = 22;
 int WP3 = 5;
 int WP4 = 878;
 int WP5 = 678;
 int WP6 = 13;
 int WP7 = 4;
 
  int array[] = {WP1, WP2, WP3, WP4, WP5, WP6, WP7};
  int count = sizeof(array) / sizeof(array[0]);
  int index = 0 ;               

  for (int i = 1; i < count; i++)
  {
    if (array[i] < array[index]) {
      index = i;
    }
  }
  Serial.print("Total Number Of WayPoints = ");
  Serial.println(count);
  Serial.print("Closest WayPoint is ");
  Serial.print(array[index]);
  Serial.println(" Meters Away");
  Serial.print("Closest Waypoint is WP");
  Serial.println(index + 1);
  delay(2000);
  Serial.println();

  
}

ian160981:
I am going to google my own thread title and kick myself :slight_smile:

You are in enough trouble without getting into recursion...

GOT IT!!

I kicked myself a load of times in the process :o
Teaching myself exactly how an array works done the trick :slight_smile:

Once I learned arrays are ZERO indexed it made sense to return the value of index + 1 to get my answer.

Thank you.

Once I learned arrays are ZERO indexed it made sense to return the value of index + 1 to get my answer.

You are not calling a function to find the smallest value, so the whole concept of "return the value" makes no sense.

If the smallest value is at position 4, using the value at position 5 makes no sense.

PaulS:
You are not calling a function to find the smallest value, so the whole concept of "return the value" makes no sense.

If the smallest value is at position 4, using the value at position 5 makes no sense.

I Will try to explain myself a little better.

There is probably a way to do this that makes more sense (or a way that's easier) but this does what I need it to do.

Not only do I want to return the lowest value from the array but I also want to find out which element has the lowest value.

The array of distances are ZERO indexed, so the first element in this case, WP1 will be element zero, WP2 will be element 1 and so on.
eg, if I have 4 WayPoints with distances pre-calculated : -
eg, WP1=125, WP2=58, WP3=25, WP4=256

the closest waypoint is WP3 with a distance of 25 Meters.
This is element 2 of the array so if I return "index" + 1 I get the desired WayPoint Number.

As I said, I am sure there will be a more sensible approach to this but I have it working the way I need it to. But at the same time I would be really grateful if you provided the proper way of doing it. I would love for my code to have as little flaws/bugs as possible.

Thanks

It seemed simple to me.

int WP1 = 43;
int WP2 = 22;
int WP3 = 5;
int WP4 = 878;
int WP5 = 678;
int WP6 = 13;
int WP7 = 4;

int array[] = {WP1, WP2, WP3, WP4, WP5, WP6, WP7};
int count = sizeof(array) / sizeof(array[0]);
int closestWayPoint = count;
int closestWayPointValue = 32767;

void setup() {
  Serial.begin(9600);
  for (int i = 0; i < count; i++)
  {
    if (array[i] < closestWayPointValue)
    {
      closestWayPointValue = array[i];
      closestWayPoint = i;
    }
  }
  Serial.print("Total Number Of WayPoints = ");
  Serial.println(count);
  Serial.print("Closest WayPoint is ");
  Serial.print(closestWayPointValue);
  Serial.println(" Meters Away");
  Serial.print("Closest Waypoint is WP");
  Serial.println(closestWayPoint);
  Serial.println();
}

void loop() {}

Thank you aarg,

That makes sense, although is that not similar to what I already have?

I think in my code it just compares all elements to element zero to return the lowest.

Whereas your example uses a base value of 32767 to compare to.

Is this right or am I missing something?

void setup() {
Serial.begin(9600);

}

void loop() {

int WP1 = 43;
int WP2 = 22;
int WP3 = 5;
int WP4 = 878;
int WP5 = 678;
int WP6 = 13;
int WP7 = 4;

int array[] = {WP1, WP2, WP3, WP4, WP5, WP6, WP7};
int count = sizeof(array) / sizeof(array[0]);
int index = 0 ; 

for (int i = 1; i < count; i++)
{
if (array[i] < array[index]) {
index = i;
}
}
Serial.print("Total Number Of WayPoints = ");
Serial.println(count);
Serial.print("Closest WayPoint is ");
Serial.print(array[index]);
Serial.println(" Meters Away");
Serial.print("Closest Waypoint is WP");
Serial.println(index + 1);
delay(2000);
Serial.println();


}

You are missing decent indentation.

My way, you can also initialize it that way.
int closestWayPointValue = array[0];Your way just saves the index, then retrieves the value later. Take your pick.

I was trying to honour your request literally:

Not only do I want to return the lowest value from the array but I also want to find out which element has the lowest value.

Sorry aarg,
I see the small but effective differences now. Im at work just now and only quickly read your example and missed the whole point :slight_smile:

Apologies for the indentation too, I always remember good indentation in my main codes when its me that has to understand it, ive no excuse for forgetting it in the forum where it probably matters the most for other people looking at.

I wouldn't worry about it, I think the point has been made that a basic algorithm has variations. Sometimes you want to save the value because it's painful to go back and retrieve it later, such as when reading a sequential file. For an array, the identity is sufficient because as you show, you can use it to obtain the value.

I think your way is easier to understand if you give "index" a better name, like "indexOfClosest".

Thanks aarg,
for making arrays a bit more simple to understand and use :slight_smile: