Task

Select certain elements from an Array into a new Array in a generic way.



To demonstrate, select all even numbers from an Array.

As an option, give a second solution which filters destructively,
by modifying the original Array rather than creating a new Array.




/* NetRexx */
options replace format comments java crossref symbols nobinary
numeric digits 5000
 
-- =============================================================================
class RFilter public
  properties indirect
    filter = RFilter.ArrayFilter
  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  method main(args = String[]) public static
    arg = Rexx(args)
    RFilter().runSample(arg)
    return
  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  method runSample(arg) public
    sd1 = Rexx[]
    sd2 = Rexx[]
 
    say 'Test data:'
    sd1 = makeSampleData(100)
    display(sd1)
    setFilter(RFilter.EvenNumberOnlyArrayFilter())
    say
    say 'Option 1 (copy to a new array):'
    sd2 = getFilter().filter(sd1)
    display(sd2)
    say
    say 'Option 2 (replace the original array):'
    sd1 = getFilter().filter(sd1)
    display(sd1)
    return
  -- ---------------------------------------------------------------------------
  method display(sd = Rexx[]) public static
    say '-'.copies(80)
    loop i_ = 0 to sd.length - 1
      say sd[i_] '\-'
      end i_
    say
    return
  -- ---------------------------------------------------------------------------
  method makeSampleData(size) public static returns Rexx[]
    sd = Rexx[size]
    loop e_ = 0 to size - 1
      sd[e_] = (e_ + 1 - size / 2) / 2
      end e_
    return sd
 
-- =============================================================================
class RFilter.ArrayFilter abstract
  -- ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
  method filter(array = Rexx[]) public abstract returns Rexx[]
-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
class RFilter.EvenNumberOnlyArrayFilter extends RFilter.ArrayFilter
  -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  method filter(array = Rexx[]) public returns Rexx[]
    clist = ArrayList(Arrays.asList(array))
    li = clist.listIterator()
    loop while li.hasNext()
      e_ = Rexx li.next
      if \e_.datatype('w'), e_ // 2 \= 0 then li.remove()
      end
    ry = Rexx[] clist.toArray(Rexx[clist.size()])
    return ry
 