142

The method should work like Math.Max(), but take 3 or more int parameters.

janw
  • 8,758
  • 11
  • 40
  • 62
JamesRedcoat
  • 2,083
  • 2
  • 15
  • 13

14 Answers14

229

You could use Enumerable.Max:

new [] { 1, 2, 3 }.Max();
KyleMit
  • 30,350
  • 66
  • 462
  • 664
Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
182

Well, you can just call it twice:

int max3 = Math.Max(x, Math.Max(y, z));

If you find yourself doing this a lot, you could always write your own helper method... I would be happy enough seeing this in my code base once, but not regularly.

(Note that this is likely to be more efficient than Andrew's LINQ-based answer - but obviously the more elements you have the more appealing the LINQ approach is.)

EDIT: A "best of both worlds" approach might be to have a custom set of methods either way:

public static class MoreMath
{
    // This method only exists for consistency, so you can *always* call
    // MoreMath.Max instead of alternating between MoreMath.Max and Math.Max
    // depending on your argument count.
    public static int Max(int x, int y)
    {
        return Math.Max(x, y);
    }

    public static int Max(int x, int y, int z)
    {
        // Or inline it as x < y ? (y < z ? z : y) : (x < z ? z : x);
        // Time it before micro-optimizing though!
        return Math.Max(x, Math.Max(y, z));
    }

    public static int Max(int w, int x, int y, int z)
    {
        return Math.Max(w, Math.Max(x, Math.Max(y, z)));
    }

    public static int Max(params int[] values)
    {
        return Enumerable.Max(values);
    }
}

That way you can write MoreMath.Max(1, 2, 3) or MoreMath.Max(1, 2, 3, 4) without the overhead of array creation, but still write MoreMath.Max(1, 2, 3, 4, 5, 6) for nice readable and consistent code when you don't mind the overhead.

I personally find that more readable than the explicit array creation of the LINQ approach.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    If you ask a question like this the performance of a max function is most likely irrelevant, and readability would prevail. – Bas Jul 23 '11 at 14:00
  • 2
    @Andrew: I think it's okay to read in *one* place. If I had it more than once (but still with 3 parameters every time), I'd probably rather write a custom method than use the LINQ approach. `MoreMath.Max(x, y, z)` is even more readable than the LINQ approach, IMO. – Jon Skeet Jul 23 '11 at 14:01
  • Why you not used just `public static int Max(params int[] values) `? – Navid Rahmani Jul 23 '11 at 19:57
  • 3
    @Navid: Because calling that as `Max(1, 2, 3)` will create an array for no reason. By providing a few overloads for relatively small numbers of parameters, you can make it more efficient without affecting readability of the caller. – Jon Skeet Jul 23 '11 at 22:27
  • Math.Max seems to consistently perform better until you optimize your code, it's lead shrinks as we go from 2 -> 3 -> 4, even adding MoreMath.Max(x, y) incures an measureable overhead. Math.Max ~ (1,2) 43ms, (2,1) ~38ms, Inlined ~ (1,2) 58ms, (2,1) ~53ms, Delegated~ (1,2) 69ms, (2,1) ~61ms. -> Math on 3 values: ~55ms, Inlined: ~62ms. -> 4 values: ~75ms vs ~80ms... All done by 10 million iterations and 5 measurements... If you turn on optimizations the trend turns and Math wins more the more values you add. But... you would need billions of comparisons before performance mattered. – Jens Jul 08 '16 at 08:41
  • This answer was useful for me – Fatemeh Ghaffari Jul 19 '20 at 19:33
33

Linq has a Max function.

If you have an IEnumerable<int> you can call this directly, but if you require these in separate parameters you could create a function like this:

using System.Linq;

...

static int Max(params int[] numbers)
{
    return numbers.Max();
}

Then you could call it like this: max(1, 6, 2), it allows for an arbitrary number of parameters.

Bas
  • 26,772
  • 8
  • 53
  • 86
  • 2
    Yup, as per my edited answer too... except I'd definitely want to call it `Max` rather than `max`, and make it static :) By overloading it for fewer parameters, you can make it more efficient too. – Jon Skeet Jul 23 '11 at 14:07
  • 1
    @Jon Skeet: should we be really writing functions for one liners like this? – naveen Jul 23 '11 at 14:24
  • 5
    @naveen: Absolutely, if it makes the code clearer, and you're using it in multiple places. Why not? – Jon Skeet Jul 23 '11 at 14:26
  • @Jon Skeet: thanks for clarifying. that was a design doubt i had for long. to or not to :) – naveen Jul 23 '11 at 14:34
14

As generic

public static T Min<T>(params T[] values) {
    return values.Min();
}

public static T Max<T>(params T[] values) {
    return values.Max();
}
The_Black_Smurf
  • 5,178
  • 14
  • 52
  • 78
Herman Schoenfeld
  • 8,464
  • 4
  • 38
  • 49
8

off topic but here is the formula for middle value.. just in case someone is looking for it

Math.Min(Math.Min(Math.Max(x,y), Math.Max(y,z)), Math.Max(x,z));
user384080
  • 4,576
  • 15
  • 64
  • 96
6

Let's assume that You have a List<int> intList = new List<int>{1,2,3} if You want to get a max value You could do

int maxValue = intList.Max();
Berial
  • 557
  • 1
  • 8
  • 23
1

If, for whatever reason (e.g. Space Engineers API), System.array has no definition for Max nor do you have access to Enumerable, a solution for Max of n values is:

public int Max(int[] values) {
    if(values.Length < 1) {
        return 0;
    }
    if(values.Length < 2) {
        return values[0];
    }
    if(values.Length < 3) {
       return Math.Max(values[0], values[1]); 
    }
    int runningMax = values[0];
    for(int i=1; i<values.Length - 1; i++) {
       runningMax = Math.Max(runningMax, values[i]);
    }
    return runningMax;
}
straya
  • 5,002
  • 1
  • 28
  • 35
1

Maximum element value in priceValues[] is maxPriceValues :

double[] priceValues = new double[3];
priceValues [0] = 1;
priceValues [1] = 2;
priceValues [2] = 3;
double maxPriceValues = priceValues.Max();
Bo Jangles
  • 51
  • 3
0

You could try this code:

private float GetBrightestColor(float r, float g, float b) { 
    if (r > g && r > b) {
        return r;
    } else if (g > r && g > b) { 
        return g;
    } else if (b > r && b > g) { 
        return b;
    }
}
Enzokie
  • 7,365
  • 6
  • 33
  • 39
Mark Aven
  • 325
  • 3
  • 8
0

This function takes an array of integers. (I completely understand @Jon Skeet's complaint about sending arrays.)

It's probably a bit overkill.

    public static int GetMax(int[] array) // must be a array of ints
    {
        int current_greatest_value = array[0]; // initializes it

        for (int i = 1; i <= array.Length; i++)
        {
            // compare current number against next number

            if (i+1 <= array.Length-1) // prevent "index outside bounds of array" error below with array[i+1]
            {
                // array[i+1] exists
                if (array[i] < array[i+1] || array[i] <= current_greatest_value)
                {
                    // current val is less than next, and less than the current greatest val, so go to next iteration
                    continue;
                }
            } else
            {
                // array[i+1] doesn't exist, we are at the last element
                if (array[i] > current_greatest_value)
                {
                    // current iteration val is greater than current_greatest_value
                    current_greatest_value = array[i];
                }
                break; // next for loop i index will be invalid
            }

            // if it gets here, current val is greater than next, so for now assign that value to greatest_value
            current_greatest_value = array[i];
        }

        return current_greatest_value;
    }

Then call the function :

int highest_val = GetMax (new[] { 1,6,2,72727275,2323});

// highest_val = 72727275
0

If you don't want to repeatedly calling the Max function, can do like this

new List<int>() { A, B, C, D, X, Y, Z }.Max()
TPG
  • 2,811
  • 1
  • 31
  • 52
0

You can use if and else if method for three values but it would be much easier if you call call twice Math.Max method like this

        Console.WriteLine("Largest of three: " + Math.Max(num1, Math.Max(num2, num3)));
        Console.WriteLine("Lowest of three: " + Math.Min(num1, Math.Min(num2, num3)));

       
    
0

For those who Googled here, Mathf.Max now supports up to 3 overloads, so this works:

Mathf.Max(1, 2, 3);
ijed
  • 1
  • 2
-2

in case you need sorting as well:

var side = new double[] {5,3,4}
Array.Sort(side);

//side[2] is a maximum

as an another variant:

T[] GetMax<T>(int number, List<T> source, T minVal)
{
  T[] results = new T[number];

  for (int i = 0; i < number; i++)
  {
    results[i] = minVal;
  }

  var curMin = minVal;

  foreach (var e in source)
  {
    int resComp = Comparer.DefaultInvariant.Compare(curMin, e);

    if (resComp < 0)
    {
      int minIndex = Array.IndexOf(results, curMin);
      results[minIndex] = e;
      curMin = results.Min();
    }
  }

  return results;
}

  var source = new int[] { 5, 5, 1, 2, 4, 3 }.ToList();
  var result = GetMax(3, source, int.MinValue);
Danil
  • 701
  • 8
  • 7
  • Please stick to answering the actual question. – Enigmativity Jun 12 '22 at 09:03
  • It answers actual question. In many cases when you search maximum you also need to sort. In fact, sorting is the way to find maximum. – Danil Jun 12 '22 at 09:26
  • Then detail how you would do that in the answer. However, sorting to find a maximum is a terrible way to do it. It's at best `nlogn` complexity when finding a max is just `n` complexity when you traverse the list once. – Enigmativity Jun 12 '22 at 10:42
  • The question is how to get 3 or more maximums. So efficiency of this approach depends on how many elements we have and how many maximums we need. If we have short array then we can not to bother about complexity, just clean code. – Danil Jun 12 '22 at 12:10
  • The question is how to get ***the*** maximum number from ***three*** values. – Enigmativity Jun 13 '22 at 03:57
  • And now you follow up with a `GetMax` implementation that doesn't use your sort approach ***and it doesn't even work***. Try it with `var source = new int[] { 5, 7, 3, 2, 4, 3 }.ToList(); var result = GetMax(4, source, int.MinValue);` – Enigmativity Jun 13 '22 at 03:58
  • I see. Ok thanks for finding error. Strange question then. Linq works perfect to find maximums of any ammount of integers. – Danil Jun 13 '22 at 11:11
  • What's the strange question? – Enigmativity Jun 13 '22 at 11:47