class Object

Public Instance Methods

nextract(*args) click to toggle source
@name nextract
@description Extract an array or hash of desired keys from an array of hashes or objects.
@params
  - First argument is always the array
  - Second argument can be a configuration Hash, which will look like
     {
       format: Array or Hash (default Array)
       flatten: true or false (default false)
       default: defaultValue (default nil)
     }
  - Remaining arguments can either be strings or symbols representing the keys to be extracted.
  - The keys can also be passed in as an Array.
  - If flatten is set to true and there is only one key to be extracted, the function will return
    a 1D array.
  Examples: `nextract([{ a: 1, b: 2 }, { a: 2, c: 5 }], { default: 0 }, ['a', 'b'])`
             `[[1, 2], [2, 0]]`
            `nextract([{ a: 5, b: 2 }, { a: 6, c: 7 }], { format: Hash }, 'a', 'b')`
             `[{ a: 5, b: 2 }, { a: 6, b: nil }]`
            `nextract([{ a: 5, b: 2 }, { a: 1, b: 1 }], 'a')`
             `[5, 1]`
@returns An Array or Hash or desired keys.

/

# File lib/nextract.rb, line 24
def nextract *args
  if not args[0].kind_of? Array
    raise "Must supply an Array as first argument."
  end
  arr = args[0]
  if args[1].kind_of? Hash
    if args[1].has_key? 'default'
      default = args[1]['default']
    elsif args[1].has_key? :default
      default = args[1][:default]
    else
      default = nil
    end
    if args[1].has_key? 'format'
      format = args[1]['format']
    elsif args[1].has_key? :format
      format = args[1][:format]
    else
      format = Array
    end
    if args[1].has_key? 'flatten'
      flatten = args[1]['flatten']
    elsif args[1].has_key? :flatten
      flatten = args[1][:flatten]
    else
      flatten = false
    end
    args = args[2..-1]
  else
    default = nil
    format = Array
    args = args[1..-1]
  end
  if args.length === 1 and args[0].kind_of? Array
    args = args[0]
  end
  ret = Array.new
  # state variable
  checked = 0x00
  arr.each { |v|
    if flatten and args.length === 1
      if v.kind_of? Hash
        if not v.has_key? args[0]
          ret.push default
        else
          ret.push v[args[0]]
        end
      else
        if not v.respond_to? args[0]
          ret.push default
        else
          ret.push v.send(args[0])
        end
      end
    else
      if format == Array
        ret.push Array.new
      else
        ret.push Hash.new
      end
      args.each { |u|
        if checked & 0x01 and not (u.kind_of? Symbol or u.kind_of? String)
          raise "Arguments must be of type String or Symbol"
        end
        if v.kind_of? Hash
          if not v.has_key? u
            if format == Array
              ret[ret.length - 1].push default
            else
              ret[ret.length - 1][u] = default
            end
          else
            if format == Array
              ret[ret.length - 1].push v[u]
            else
              ret[ret.length - 1][u] = v[u]
            end
          end
        else
          if not v.respond_to? u
            if format == Array
              ret[ret.length - 1].push default
            else
              ret[ret.length - 1][u] = default
            end
          else
            if format == Array
              ret[ret.length - 1].push v.send(u)
            else
              ret[ret.length - 1][u] = v.send(u)
            end
          end
        end
      }
      #define CHECKED_ARGUMENTS 0x01
      checked |= 0x01
    end
  }
  return ret
end