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))
    
    
    Run
    
    
    $ ./t
    1
    (w: 3.14)
    1
    Nim
    
    
    Run

Reply via email to