May these already exist somewhere, or may there exist better names?
proc maxIndexBy*[T](s: openArray[T], cmp: proc (x, y: T): int {.closure.}): int =
## Returns the index of the maximum value of all elements in s.
## Comparison is done by cmp() proc.
##
## Example:
##
## .. code-block:
## assert ["Go", "Nim", "C++", "D"].maxIndexBy(proc (x,y: string): int = cmp(x.len, y.len)) == 1
if s.len > 0:
var maxVal = s[0]
for i in 1 .. s.high:
if cmp(s[i], maxVal) > 0:
result = i
maxVal = s[i]
proc maxValueBy*[T](s: openArray[T], cmp: proc (x, y: T): int {.closure.}): T =
## Returns the maximum value of all elements in s.
## Comparison is done by cmp() proc.
##
## Example:
##
## .. code-block:
## assert ["Go", "Nim", "C++", "D"].maxValueBy(proc (x,y: string): int = cmp(x.len, y.len)) == "Nim"
assert(s.len > 0)
result = s[0]
if s.len > 0:
var maxVal = s[0]
for i in 1 .. s.high:
if cmp(s[i], maxVal) > 0:
result = s[i]
maxVal = s[i]
when isMainModule:
type
P = object
w: float
var a = P(w: 2.7)
var b = P(w: 3.14)
echo [a, b].maxIndexBy(proc (x, y: P): int = cmp(x.w, y.w))
echo [a, b].maxValueBy(proc (x, y: P): int = cmp(x.w, y.w))
# echo repr([a, b].maxValueBy(proc (x, y: P): int = cmp(x.w, y.w)))
echo ["Go", "Nim", "C++", "D"].maxIndexBy(proc (x,y: string): int = cmp(x.len, y.len))
echo ["Go", "Nim", "C++", "D"].maxValueBy(proc (x,y: string): int = cmp(x.len, y.len))
$ ./t
1
(w: 3.14)
1
Nim