Skip to content

Instantly share code, notes, and snippets.

@am-kantox
Created April 9, 2015 12:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save am-kantox/e9f66b73d115af4a64e2 to your computer and use it in GitHub Desktop.
Save am-kantox/e9f66b73d115af4a64e2 to your computer and use it in GitHub Desktop.
Sensible Arrays
module Sensible
module Array
class ::Array
alias_method :select_std, :select
def select arg = nil, &cb
preselected = case arg
# no argument ⇒ standard processing
when NilClass then self
# strings are matched as is
when String then select_std do |e|
e.is_a?(String) && e =~ Regexp.new(Regexp.escape(arg))
end
# return only same and derived classes
when Class then select_std do |e|
e < arg
end
# inclusive deep recurse
when Array then arg.inject([]) do |memo, e|
memo + select(e)
end.uniq
# for any other use `=~` operator
else select_std do |e|
begin
e.respond_to?(:to_s) && e.to_s =~ arg
rescue TypeError => e
false
end
end
end
block_given? ? preselected.send(:select_std, &cb) : preselected
end
private :select_std
def to_proc
lambda do |item|
case item
when Hash then item.select { |k, _| self.include? k }
when Class
map do |i|
if i.respond_to?(:to_sym)
is = i.to_sym
[
item.singleton_methods.include?(is) ? item.singleton_method(is) : nil,
item.instance_methods.include?(is) ? item.instance_method(is) : nil
]
else
[nil, nil]
end
end
when lambda do |it|
count do |i|
i.respond_to?(:to_sym) && it.respond_to?(i.to_sym)
end == length # > 0 might be an option
end then map { |m| item.send(m) }
else item.send(*self)
end
end
end
end
end
end
@am-kantox
Copy link
Author

p [Integer, Fixnum, String].select(Numeric)
# [Integer, Fixnum]

p ['one', 'two', 'three'].select('o')
# ["one", "two"]

p ['one', 'two', 'three'].select(/\At/)
# ["two", "three"]

p [Integer, Fixnum].map &[:to_s, 'to_f']
# [
#    [[nil, #<UnboundMethod: Integer(Kernel)#to_s>], [nil, nil]], 
#    [[nil, #<UnboundMethod: Fixnum#to_s>], [nil, #<UnboundMethod: Fixnum#to_f>]]
# ]

p [{a: 1, b: 2, c: 3}].map(&[:a, :c])
# [{:a=>1, :c=>3}]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment