# min / max / etc

Definition: | object res = min(object x, y) -- or -- object res = min(sequence s) (see technicalia) -- or -- object res = smallest(sequence s, bool return_index=false) -- or -- object res = sq_min(object a, b)
Description: | Returns the smallest of x and y, or the smallest element in sequence s. Atoms are considered to be less than sequences. Sequences are compared "alphabetically" (case sensitive, ie 'Z'<'a') starting with the first element until a difference is found. The sq_min(a,b) function applies min() to the top-level elements of a and b when they are both sequences, in which case they must be the same length, otherwise it applies an atom to all the elements of the other, or if they are both atoms it behaves identically to min(a,b). The result is a sequence in all but the latter case. Note that it is not recursive, and passing a single argument to sq_min() is not allowed. As of 1.0.3, the smallest() function became a simple alias of minsq(), and is now the preferred name. There are similar functions max(), sq_max(), maxsq(), and largest() for obtaining (you’ve guessed it) the largest. There are no sq_smallest or sq_largest routines.
Additional: | atom res = median(sequence s) s must be a non-empty sequence on entry, and pre-sorted for meaningful results (not verified). Returns the middle element for odd-length sequences, or the average of the middle two elements for even-length sequences. Yields the same result as average() when the spread is perfectly balanced, eg {1,40,50,60,99}.
pwa/p2js: | Supported.
Example: |
    a = min(7,5)                            -- a is 5
    b = min({9,7,5})                        -- b is 5
    c = min("two","three")                  -- c is "three"
    d = min({"one","two","three","four"})   -- d is "four"
    s = sq_min(s,1)         -- no element of s is now > 1
    ?smallest({"this",{3,5,7},9})       -- prints 9
    ?largest({"this",{3,5,7},9})        -- prints "this"
Implementation: | See builtins\pmaths.e (an autoinclude), and psqop.e, and the technicalia dropdown, for details of the actual implementation.
See Also: | equal, compare, relational operators, sequence operations
Technicalia | min(s) is an "alias" for smallest(s) aka minsq(s); the compiler automatically substitutes the function when only one parameter is passed. [At some point I should probably just retire minsq and force the use of smallest, ditto maxsq/largest.] [Mind you, I have half a mind to retire sq_min() as well, since apply() should do perfectly well enough.] Note that providing the return_index parameter prevents such a substitution, ie min(s,true) is just plain wrong, as is minsq(x,y). (To clarify that, min(s,true) would just return the true, unless there was something smaller in s, and never an index.) Both routines are declared in builtins\pmaths.e (an auto-include). Some extra care must be taken with routine_id("min"), as obviously no equivalent mapping occurs for the one or two parameter cases. The Euphoria version of min() only accepts a single argument and behaves (via self-recursion) as smallest(flatten(s)), whereas the Phix version is not recursive. Unlike the Euphoria version, min(<atom>) generates a runtime error, as does min({}). This function is only compatible with Euphoria when passed a single argument that is a non-empty and non-nested sequence of atoms. Unlike several other functions the min() and sq_min() functions are not recursive. Should you (for some strange reason) believe that min({"one","two","three"}) should yield 'e', or min({}) should yield +inf, then may I politely suggest that you go away and write your own version of this routine. The smallest/largest functions differ from the Euphoria versions in std\stats.e in (at least) three ways: * The set passed in the first parameter must be a non-empty sequence (compilation or run-time error if passed an atom or {}) * It can return non-atoms in the set (if no atoms occur, it will be the first/last in an alphabetical and case-sensitive ordering) * It can return the index of the lowest/highest entry, rather than only the actual value of said. None of that should cause sensibly-written code to be incompatible or misbehave (imho/ymmv).