Class: Array
- Defined in:
- lib/rmtools/enumerable/array_iterators.rb,
lib/rmtools/rand/array.rb,
lib/rmtools/dev/present.rb,
lib/rmtools/core/arguments.rb,
lib/rmtools/enumerable/array.rb
Overview
- 1, 2, 3].to_ss # => [‘1’, ‘2’, ‘3’
-
[[1,2,3], [4,5,6], [7,8,9]].to_sss
> [[“1”, “2”, “3”], [“4”, “5”, “6”], [“7”, “8”, “9”]]
[[“1”, “2”, “3”], [“4”, “5”, “6”], [“7”, “8”, “9”]].subss!(/d+/) {|m| (m.to_i % 3).to_s}
> [[“1”, “2”, “0”], [“1”, “2”, “0”], [“1”, “2”, “0”]]
[[1, 2, 0], [1, 2, 0], [1, 2, 0]].sum_zeros?
> [false, false, true, false, false, true, false, false, true]
[[1, 2, 3], [3, 4, 6], [3, 8, 0]].uniq_by_odds?
> [[1, 2, 3], [3, 4, 6]]
Direct Known Subclasses
Constant Summary collapse
- @@iterators_names =
[]
Class Method Summary collapse
- .add_iterator_name(name_or_list) ⇒ Object
- .fallback_to_clean_iterators! ⇒ Object
- .rand(len) ⇒ Object
Instance Method Summary collapse
- #&(ary) ⇒ Object
- #+(ary) ⇒ Object
- #-(ary) ⇒ Object
-
#===(obj) ⇒ Object
making multiple pattern matching possible: a, b = ‘3’, ‘10’ case [a, b] when [Integer, Integer]; a+b when [/d/, ‘10’]; ‘%*d’%[a, b] …
-
#>>(ary) ⇒ Object
concatenation analogue to String#>>.
- #^(ary) ⇒ Object (also: #diff)
-
#arrange(*args) ⇒ Object
Make hash with unique items of
selfor (when block given) unique results of items yield for keys and count of them inself, or (with option :fill) arrays of yield results, or (with option :indexes) arrays of indexes of them, or (with option :group) arrays of themselves for values. -
#arrange_by(*args, &block) ⇒ Object
C-function, see it in /ext.
-
#as_box(opts = {}) ⇒ Object
draw array as box just calls #inspect if max element.inspect size is greater than console width.
-
#avg ⇒ Object
arithmetics.
-
#avg_by(&block) ⇒ Object
for use with iterators.
- #casecmp ⇒ Object
- #del_all_where(&block) ⇒ Object
- #del_where(&block) ⇒ Object
-
#div(int, to_int_parts = nil) ⇒ Object
splitters.
- #div!(int, to_int_parts = nil) ⇒ Object
- #each_two ⇒ Object
- #evens ⇒ Object
-
#every? ⇒ Boolean
conditional.
-
#fetch_opts(defaults = [], opts = {}) ⇒ Object
(also: #fetch_options, #get_opts)
a, b, opts = [<hash1>].fetch_opts([<hash2>, <object1>]) may work unintuitive: you’ll get <hash1> as ‘a’ and not as ‘opts’ So if function is not implying that some argument other than ‘opts’ definetly must be a hash, don’t make hash default.
-
#find_by(key, value) ⇒ Object
find-by-value filters It’s more of a pattern.
-
#group_by(&b) ⇒ Object
fastering activesupport’s method.
- #index_where(&block) ⇒ Object (also: #pos)
- #indices_map ⇒ Object (also: #addresses)
- #indices_where(&block) ⇒ Object
- #intersects?(ary) ⇒ Boolean (also: #x?)
-
#map_with_index(&block) ⇒ Object
enumerating.
-
#method_missing(method, *args, &block) ⇒ Object
Benchmark 3:.
- #no? ⇒ Boolean
-
#odds ⇒ Object
filters.
-
#partition {|obj| ... } ⇒ Array
Same as Enumerable#partition, but twice faster.
- #present(inspect_string = nil) ⇒ Object
- #rand ⇒ Object
- #rand! ⇒ Object
- #rand_by ⇒ Object
- #randdiv(int) ⇒ Object
- #randdiv!(int) ⇒ Object
- #reject_by(key, value) ⇒ Object
-
#rfind ⇒ Object
rightmost #find.
-
#rfind_by(key, value) ⇒ Object
rightmost #find_by.
-
#runiq ⇒ Object
rightmost #uniq.
-
#runiq_by(&block) ⇒ Object
rightmost #uniq_by.
- #scale(top) ⇒ Object
- #select_by(key, value) ⇒ Object
- #set_all_where(value, &block) ⇒ Object
-
#set_where(value, &block) ⇒ Object
setters/getters/deleters.
- #sort_along_by(ary) ⇒ Object
-
#sorted_uniq_by(&block) ⇒ Object
sort / group.
-
#stranspose ⇒ Object
puts [‘123’, ‘456’, ‘789’].stranspose 147 258 369.
-
#sum(identity = 0, &b) ⇒ Object
mapreduce.
- #throw_no ⇒ Object
-
#turn_ccw ⇒ Object
puts [‘123’, ‘456’, ‘789’].turn_ccw 369 258 147.
-
#turn_cw ⇒ Object
puts [‘123’, ‘456’, ‘789’].turn_cw 147 258 369.
-
#uniq? ⇒ Boolean
uniqs.
-
#uniq_by ⇒ Object
Safe version of uniq_by!.
-
#uniq_by! ⇒ Object
Modifies array, throwing all elements not having unique block result a = randarr 10 => [8, 2, 0, 5, 4, 1, 7, 3, 9, 6] a.uniq_by! {|e| e%2} => [8, 5] a => [8, 5] Here is implyied that callback block is clean function.
- #valid_types(pattern_ary) ⇒ Object
- #|(ary) ⇒ Object
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
Benchmark 3:
# 3.2. Meta calls: # 3.2.1: = (13 * 10^6 x #__send__) timer(1_000_000) { [[1, 2, 3], [3, 4, 6], [3, 8, 0]].uniq_by_odds? } one: 0.0145ms, total: 14520.0ms # = 11% of time a = (0…300).to_a.map 300; # 3.2.2: = (9 * 10^6 x #__send__) timer(100) { a.uniq_by_odds? } one: 36.1000ms, total: 3610.0ms # = 6% of time
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/rmtools/enumerable/array_iterators.rb', line 220 def method_missing(method, *args, &block) if match = (meth = method.to_s).match(@@iterators_pattern) iterator, meth = match[1].to_sym, match[2].to_sym case iterator when :every then iterator = :every? when :no then iterator = :no? end case iterator when :sum, :sort_along_by Array.class_eval %{ def #{method}(*args, &block) # sum_posts_ids([], :all) => # sum([]) {|e| e.posts_ids(:all)} #{iterator}(args.shift) {|e| e.#{meth}(*args, &block)} rescue NoMethodError => err err.message << " (`#{method}' interpreted as decorator-function `#{meth}')" raise err end} when :find_by, :rfind_by,:select_by, :reject_by Array.class_eval %{ def #{method}(val) # select_by_count(max_count) => # select {|e| e.count == max_count} #{iterator.to_s[0...-3]} {|e| e.#{meth} == val} rescue NoMethodError => err err.message << " (`#{method}' interpreted as decorator-function `#{meth}')" raise err end} else Array.class_eval %{ def #{method}(*args, &block) # uniq_by_sum(1) {|i| 1 / i.weight} => # uniq_by {|e| e.sum(1) {|i| 1 / i .weight}} #{iterator} {|e| e.#{meth}(*args, &block)} rescue NoMethodError => err err.message << " (`#{method}' interpreted as decorator-function `#{meth}')" raise err end} end elsif meth.sub!(/sses([=!?]?)$/, 'ss\1') or meth.sub!(/ies([=!?]?)$/, 'y\1') or meth.sub!(/s([=!?]?)$/, '\1') assignment = meth =~ /=$/ meth = meth.to_sym if assignment Array.class_eval %{ def #{method}(value) if Array === value # owner_ids = users_ids => # each_with_index {|e, i| e.owner_id = users_ids[i]} each_with_index {|e, i| e.#{meth} value[i]} else # owner_ids = user_id => # each {|e, i| e.owner_id = user_id} each {|e| e.#{meth} value} end rescue NoMethodError => err err.message << " (`#{method}' interpreted as map-function `#{meth}')" raise err end} else Array.class_eval %{ def #{method}(*args, &block) # to_is(16) => # map {|e| e.to_i(16)} map {|e| e.#{meth}(*args, &block)} rescue NoMethodError => err err.message << " (`#{method}' interpreted as map-function `#{meth}')" raise err end} end else return throw_no method end __send__(method, *args, &block) end |
Class Method Details
.add_iterator_name(name_or_list) ⇒ Object
20 21 22 23 24 |
# File 'lib/rmtools/enumerable/array_iterators.rb', line 20 def add_iterator_name(name_or_list) name_or_list = [name_or_list] if !name_or_list.is Array @@iterators_names |= name_or_list @@iterators_pattern = %r{^(#{@@iterators_names*'|'})_([\w\d\_]+[!?]?)} end |
.fallback_to_clean_iterators! ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/rmtools/enumerable/array_iterators.rb', line 26 def fallback_to_clean_iterators! class_eval do # Benchmark 1: # # We take a simple methods like uniq_by (O(N)) and odd? (O(1)) to ensure that # # penalty we would have in production would not be larger than that in bench # # # 1.1. Traditional calls: # # 1.1.1: (9 x #odd? + 3 x #map + 1 x #uniq_by) * 10^6 # timer(1_000_000) { [[1, 2, 3], [3, 4, 6], [3, 8, 0]].uniq_by {|i| i.map {|j| j.odd?}} } # one: 0.0130ms, total: 13040.0ms # # 1.1.2: (90_000 x #odd? + 300 x #map + 1 x #uniq_by) * 100 # timer(100) { a.uniq_by {|i| i.map {|j| j.odd?}} } # one: 34.0000ms, total: 3400.0ms # # # 1.2. Meta calls: # # 1.2.1: += (13 * 10^6 x #__send__) + (4 * 10^6 x #method_missing) # timer(1_000_000) { [[1, 2, 3], [3, 4, 6], [3, 8, 0]].uniq_by_odds? } # one: 0.0354ms, total: 35440.0ms # # += 172% of time # a = (0...300).to_a.map {Array.rand 300}; # # 1.2.2: += (9 * 10^6 x #__send__) + (30_100 x #method_missing) # timer(100) { a.uniq_by_odds? } # one: 39.3000ms, total: 3930.0ms # # += 16% of time # # Conclusion: # # 1. If we want to speed meta-calls up, we should sacrifice cleanness of Array namespace, # I mean define missing methods inplace. # 2. Most latency is given by #method_missing, but which are factor of #__send__? def method_missing(method, *args, &block) if match = (meth = method.to_s).match(@@iterators_pattern) iterator, meth = match[1].to_sym, match[2].to_sym begin case iterator when :every then iterator = :every? when :no then iterator = :no? end return case iterator when :sum, :sort_along_by; __send__(iterator, args.shift) {|i| i.__send__ meth, *args, &block} when :find_by, :select_by, :reject_by; __send__(iterator, meth, *args) else __send__(iterator) {|i| i.__send__ meth, *args, &block} end rescue NoMethodError => e e. << " (`#{method}' interpreted as decorator-function `#{meth}')" raise e end elsif meth.sub!(/sses([=!?]?)$/, 'ss\1') or meth.sub!(/ies([=!?]?)$/, 'y\1') or meth.sub!(/s([=!?]?)$/, '\1') assignment = meth =~ /=$/ meth = meth.to_sym begin if assignment if Array === args each_with_index {|e,i| e.__send__ meth, args[i]} else each {|e| e.__send__ meth, args} end else map {|e| e.__send__ meth, *args, &block} end rescue NoMethodError => e e. << " (`#{method}' interpreted as map-function `#{meth}')" raise e end else throw_no method end end end # class_eval end |
Instance Method Details
#&(ary) ⇒ Object
45 46 47 48 49 50 |
# File 'lib/rmtools/enumerable/array.rb', line 45 def &(ary) if empty? or (ary.respond_to? :empty? and ary.empty?) [] else intersection(ary) end end |
#+(ary) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/rmtools/enumerable/array.rb', line 24 def +(ary) if empty? if ary.respond_to? :empty? and ary.empty? [] else ary.dup end elsif ary.respond_to? :empty? and ary.empty? dup else coallition(ary) end end |
#-(ary) ⇒ Object
36 37 38 39 40 41 42 43 |
# File 'lib/rmtools/enumerable/array.rb', line 36 def -(ary) if empty? [] elsif ary.respond_to? :empty? and ary.empty? dup else subtraction(ary) end end |
#===(obj) ⇒ Object
making multiple pattern matching possible: a, b = ‘3’, ‘10’ case [a, b]
when [Integer, Integer]; a+b
when [/\d/, '10']; '%*d'%[a, b]
...
end
symbol :~ stands for Object
248 249 250 251 252 |
# File 'lib/rmtools/enumerable/array.rb', line 248 def ===(obj) return true if casecmp(obj) !!(obj.kinda(Array) and obj.size == size and each_with_index {|e, i| e == :~ or e === obj[i] or return false}) end |
#>>(ary) ⇒ Object
concatenation
analogue to String#>>
232 233 234 |
# File 'lib/rmtools/enumerable/array.rb', line 232 def >>(ary) ary.replace(self + ary) end |
#^(ary) ⇒ Object Also known as: diff
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/rmtools/enumerable/array.rb', line 52 def ^(ary) if empty? or (ary.respond_to? :empty? and ary.empty?) [dup, ary.dup] elsif self == ary [[], []] else common = intersection ary [self - common, ary - common] end end |
#arrange(*args) ⇒ Object
Make hash with unique items of self or (when block given) unique results of items yield for keys and count of them in self, or (with option :fill) arrays of yield results, or (with option :indexes) arrays of indexes of them, or (with option :group) arrays of themselves for values
[1, 2, 2, 2, 3, 3].arrange
> 2=>3, 3=>2
[1, 2, 2, 2, 3, 3].arrange {|i| i%2}
> 1=>3
[1, 2, 2, 2, 3, 3].arrange :fill
> , 2=>[2, 2, 2], 3=>[3, 3]
[1, 2, 2, 2, 3, 3].arrange :indexes
> , 2=>[1, 2, 3], 3=>[4, 5]
[1, 2, 2, 2, 3, 3].arrange(:indexes) {|i| i%2}
> 2, 3], 1=>[0, 4, 5]
:group is analogue to rails’ group_by but twice faster [1, 2, 2, 2, 3, 3].arrange(:group) {|i| i%2}
> 2, 2], 1=>[1, 3, 3]
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'ext/rmtools.cpp', line 256
static VALUE rb_ary_count_items(int argc, VALUE *argv, VALUE ary)
{
long i, alen, block_given;
int fill, ind, group;
VALUE key, arg, storage;
VALUE hash = rb_hash_new();
VALUE val = Qnil;
block_given = rb_block_given_p();
rb_scan_args(argc, argv, "01", &arg);
ind = arg == ID2SYM(rb_intern("indexes"));
group = arg == ID2SYM(rb_intern("group"));
fill = ind || group || arg == ID2SYM(rb_intern("fill"));
alen = RARRAY_LEN(ary);
for (i=0; i<RARRAY_LEN(ary); i++) {
key = block_given ? rb_yield(RARRAY_PTR(ary)[i]) : RARRAY_PTR(ary)[i];
if (fill)
{
if (st_lookup(RHASH_TBL(hash), key, 0))
storage = rb_hash_aref(hash, key);
else {
storage = rb_ary_new2(alen);
rb_hash_aset(hash, key, storage);
}
rb_ary_push(storage, ind ? LONG2FIX(i) : group ? RARRAY_PTR(ary)[i] : key);
}
else {
if (st_lookup(RHASH_TBL(hash), key, &val))
rb_hash_aset(hash, key, LONG2FIX(FIX2LONG(val) + 1));
else
rb_hash_aset(hash, key, INT2FIX(1));
}
}
return hash;
}
|
#arrange_by(*args, &block) ⇒ Object
C-function, see it in /ext
209 210 211 |
# File 'lib/rmtools/enumerable/array.rb', line 209 def arrange_by(*args, &block) arrange(*args, &block) end |
#as_box(opts = {}) ⇒ Object
draw array as box just calls #inspect if max element.inspect size is greater than console width
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/rmtools/dev/present.rb', line 25 def as_box(opts={}) opts = {:max_cols => Inf, :padding => 0}.merge opts return inspect unless cols = ENV['COLUMNS'] cols = cols.to_i cell_size = map {|e| e.inspect.csize}.max + opts[:padding]*2 if n = [(1..cols/2).max {|i| i*(cell_size+1) < cols}, opts[:max_cols]].min table = div(n) border = '+'+('-'*cell_size+'+')*n need_lb = border.size < cols border << "\n" if need_lb last_border = table.last.size == n ? border : '+'+('-'*cell_size+'+')*table.last.size + '-'*((cell_size+1)*(n-table.last.size)-1) + '+' table.map {|rows| str = '|'+rows.map {|cell| cell.inspect.ccenter(cell_size)}*'|'+'|' str << ' '*((cell_size+1)*(n-rows.size)-1)+'|' if rows.size < n border + str + ("\n" if need_lb) }.join + last_border else inspect end end |
#avg ⇒ Object
arithmetics
71 72 73 |
# File 'lib/rmtools/enumerable/array.rb', line 71 def avg empty? ? nil : sum.to_f/size end |
#avg_by(&block) ⇒ Object
for use with iterators
76 77 78 |
# File 'lib/rmtools/enumerable/array.rb', line 76 def avg_by(&block) empty? ? nil : sum(&block).to_f/size end |
#casecmp ⇒ Object
238 |
# File 'lib/rmtools/enumerable/array.rb', line 238 alias :casecmp :=== |
#del_all_where(&block) ⇒ Object
120 121 122 |
# File 'lib/rmtools/enumerable/array.rb', line 120 def del_all_where(&block) reject!(&block) end |
#del_where(&block) ⇒ Object
115 116 117 118 |
# File 'lib/rmtools/enumerable/array.rb', line 115 def del_where(&block) each_with_index {|e, i| return delete_at i if block[e]} nil end |
#div(int, to_int_parts = nil) ⇒ Object
splitters
127 128 129 130 131 132 133 134 135 136 |
# File 'lib/rmtools/enumerable/array.rb', line 127 def div(int, to_int_parts=nil) len = int.to_i return [self] if len <= 0 arr = dup newarr = [] while arr.size > 0 newarr << arr.slice!(0, len) end newarr end |
#div!(int, to_int_parts = nil) ⇒ Object
138 139 140 |
# File 'lib/rmtools/enumerable/array.rb', line 138 def div!(int, to_int_parts=nil) replace(div(int, to_int_parts)) end |
#each_two ⇒ Object
261 262 263 264 265 266 267 268 |
# File 'lib/rmtools/enumerable/array.rb', line 261 def each_two _end = size-1 self[0..-2].each_with_index {|u, i| (i+1.._end).each {|j| yield u, self[j] } } end |
#evens ⇒ Object
148 149 150 |
# File 'lib/rmtools/enumerable/array.rb', line 148 def evens values_at(*(0...size).evens) end |
#every? ⇒ Boolean
conditional
153 154 155 |
# File 'lib/rmtools/enumerable/array.rb', line 153 def every? !find {|e| !yield(e)} end |
#fetch_opts(defaults = [], opts = {}) ⇒ Object Also known as: fetch_options, get_opts
a, b, opts = [<hash1>].fetch_opts([<hash2>, <object1>]) may work unintuitive: you’ll get <hash1> as ‘a’ and not as ‘opts’ So if function is not implying that some argument other than ‘opts’ definetly must be a hash, don’t make hash default. Better put hashie argument into opts like b, opts = [<hash1>].fetch(, :a => <hash2>) and get ‘a’ from ‘’opts’ hash
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/rmtools/core/arguments.rb', line 11 def fetch_opts(defaults=[], opts={}) if Hash === defaults opts, defaults = defaults, [] return_hash = true $log.warn "fetch_opts(<hash>) now changed, if you want to jsut fetch hash options, use `opts = <hash>.merge(opts||{})' construction", :caller => 2 else return_hash = false end opts &&= if Hash === self[-1] and !(Hash === defaults[size-1]) opts.merge pop else opts.dup end return opts if return_hash if defaults == :flags defauls = [:flags] end if defaults.last == :flags defaults.pop flags = defaults.size..-1 if defaults.size < size self[flags].each {|flag| opts[flag] = true} self[flags] = [] end end each_index {|i| import(defaults, i) if :def == self[i]} defaults.slice! 0, size concat defaults << opts end |
#find_by(key, value) ⇒ Object
find-by-value filters It’s more of a pattern. Use of respective meta-iterators is prefered.
169 170 171 |
# File 'lib/rmtools/enumerable/array.rb', line 169 def find_by(key, value) find {|e| e.__send__(key) == value} end |
#group_by(&b) ⇒ Object
fastering activesupport’s method
278 279 280 |
# File 'lib/rmtools/enumerable/array.rb', line 278 def group_by(&b) arrange(:group, &b) end |
#index_where(&block) ⇒ Object Also known as: pos
103 104 105 106 |
# File 'lib/rmtools/enumerable/array.rb', line 103 def index_where(&block) each_with_index {|e, i| return i if block[e]} nil end |
#indices_map ⇒ Object Also known as: addresses
213 214 215 216 217 |
# File 'lib/rmtools/enumerable/array.rb', line 213 def indices_map addresses = {} (size-1).downto(0) {|i| addresses[self[i]] = i} addresses end |
#indices_where(&block) ⇒ Object
109 110 111 112 113 |
# File 'lib/rmtools/enumerable/array.rb', line 109 def indices_where(&block) a = [] each_with_index {|e, i| a << i if block[e]} a end |
#intersects?(ary) ⇒ Boolean Also known as: x?
65 66 67 |
# File 'lib/rmtools/enumerable/array.rb', line 65 def intersects?(ary) (self & ary).any? end |
#map_with_index(&block) ⇒ Object
enumerating
257 258 259 |
# File 'lib/rmtools/enumerable/array.rb', line 257 def map_with_index(&block) each_with_index.map(&block) end |
#no? ⇒ Boolean
157 158 159 |
# File 'lib/rmtools/enumerable/array.rb', line 157 def no? !find {|e| yield(e)} end |
#odds ⇒ Object
filters
144 145 146 |
# File 'lib/rmtools/enumerable/array.rb', line 144 def odds values_at(*(0...size).odds) end |
#partition {|obj| ... } ⇒ Array
Same as Enumerable#partition, but twice faster
[5, 6, 1, 2, 4, 3].partition {|i| (i&1).zero?} #=> [[2, 4, 6], [1, 3, 5]]
303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'ext/rmtools.cpp', line 303
static VALUE rb_ary_partition(VALUE ary)
{
VALUE select, reject;
long i, len;
RETURN_ENUMERATOR(ary, 0, 0);
len = RARRAY_LEN(ary);
select = rb_ary_new2(len);
reject = rb_ary_new2(len);
for (i = 0; i < len; i++)
rb_ary_push((RTEST(rb_yield(RARRAY_PTR(ary)[i])) ? select : reject), RARRAY_PTR(ary)[i]);
return rb_assoc_new(select, reject);
}
|
#present(inspect_string = nil) ⇒ Object
13 14 15 16 17 18 19 20 21 |
# File 'lib/rmtools/dev/present.rb', line 13 def present(inspect_string=nil) res = "[ " indent = (size-1).to_s.size res << map_with_index {|k,i| "#{RMTools::Painter.w(i.to_s.rjust(indent))}: #{(k.is String and !inspect_string) ? k : k.inspect}" }*"\n " res << "]" puts res end |
#rand ⇒ Object
20 21 22 |
# File 'lib/rmtools/rand/array.rb', line 20 def rand self[Kernel.rand(size)] end |
#rand! ⇒ Object
24 25 26 |
# File 'lib/rmtools/rand/array.rb', line 24 def rand! delete_at Kernel.rand size end |
#rand_by ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/rmtools/rand/array.rb', line 28 def rand_by return if empty? set, ua = Set.new, uniq s = ua.size loop { i = Kernel.rand size if set.include? i return if set.size == s elsif yield(e = ua[i]) return e else set << i end } end |
#randdiv(int) ⇒ Object
43 44 45 |
# File 'lib/rmtools/rand/array.rb', line 43 def randdiv(int) dup.randdiv!(int) end |
#randdiv!(int) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/rmtools/rand/array.rb', line 47 def randdiv!(int) len = 2*int.to_i+1 return [self] if len <= 1 newarr = [] while size > 0 lenn = Kernel.rand(len) next if lenn < 1 newarr << slice!(0, lenn) end newarr end |
#reject_by(key, value) ⇒ Object
183 184 185 |
# File 'lib/rmtools/enumerable/array.rb', line 183 def reject_by(key, value) reject {|e| e.__send__(key) == value} end |
#rfind ⇒ Object
rightmost #find
162 163 164 165 |
# File 'lib/rmtools/enumerable/array.rb', line 162 def rfind reverse_each {|e| return e if yield e} nil end |
#rfind_by(key, value) ⇒ Object
rightmost #find_by
174 175 176 177 |
# File 'lib/rmtools/enumerable/array.rb', line 174 def rfind_by(key, value) reverse_each {|e| return e if e.__send__(key) == value} nil end |
#runiq ⇒ Object
rightmost #uniq
194 195 196 |
# File 'lib/rmtools/enumerable/array.rb', line 194 def runiq reverse.uniq.reverse end |
#runiq_by(&block) ⇒ Object
rightmost #uniq_by
199 200 201 |
# File 'lib/rmtools/enumerable/array.rb', line 199 def runiq_by(&block) reverse.uniq_by(&block).reverse end |
#scale(top) ⇒ Object
80 81 82 83 84 85 86 87 |
# File 'lib/rmtools/enumerable/array.rb', line 80 def scale(top) case top when Numeric; ratio = max.to_f/top when Array; ratio = zip(top).map {|a,b| b ? a.to_f/b : 0}.max else raise TypeError, "number or array of numbers expected, #{top.class} given" end map {|e| e/ratio} end |
#select_by(key, value) ⇒ Object
179 180 181 |
# File 'lib/rmtools/enumerable/array.rb', line 179 def select_by(key, value) select {|e| e.__send__(key) == value} end |
#set_all_where(value, &block) ⇒ Object
96 97 98 99 100 101 |
# File 'lib/rmtools/enumerable/array.rb', line 96 def set_all_where(value, &block) #select(&block).each {|e| self[index(e)] = value} # 3.643 #each_with_index {|e, i| self[i] = value if block[e]} # 0.240 # велосипедист, бля map! {|e| block[e] ? value : e} # 0.168 end |
#set_where(value, &block) ⇒ Object
setters/getters/deleters
91 92 93 94 |
# File 'lib/rmtools/enumerable/array.rb', line 91 def set_where(value, &block) each_with_index {|e, i| return self[i] = value if block[e]} nil end |
#sort_along_by(ary) ⇒ Object
220 221 222 223 224 225 226 227 228 |
# File 'lib/rmtools/enumerable/array.rb', line 220 def sort_along_by(ary) # Condition is relevant for ruby 1.9, I haven't tested it on 1.8 yet if size*ary.size > 400 addresses = ary.indices_map sort_by {|e| addresses[yield(e)]} else sort_by {|e| ary.index yield e} end end |
#sorted_uniq_by(&block) ⇒ Object
sort / group
204 205 206 |
# File 'lib/rmtools/enumerable/array.rb', line 204 def sorted_uniq_by(&block) uniq_by(&block).sort_by(&block) end |
#stranspose ⇒ Object
puts [‘123’, ‘456’, ‘789’].stranspose 147 258 369
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'ext/rmtools.cpp', line 44
static VALUE rb_ary_string_transpose(VALUE ary)
{
long elen = -1, alen, i, j;
VALUE tmp, result = 0;
alen = RARRAY_LEN(ary);
if (alen == 0) return rb_ary_dup(ary);
for (i=0; i<alen; i++) {
tmp = RARRAY_PTR(ary)[i];
if (elen < 0) { /* first element */
elen = RSTRING_LEN(tmp);
result = rb_ary_new2(elen);
for (j=0; j<elen; j++) rb_ary_store(result, j, rb_str_new("", 0));
}
else if (elen != RSTRING_LEN(tmp))
rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
RARRAY_LEN(tmp), elen);
for (j=0; j<elen; j++) rb_str_buf_cat(RARRAY_PTR(result)[j], &(RSTRING_PTR(tmp)[j]), 1);
}
return result;
}
|
#sum(identity = 0, &b) ⇒ Object
mapreduce
273 274 275 |
# File 'lib/rmtools/enumerable/array.rb', line 273 def sum(identity=0, &b) foldl(:+, &b) || identity end |
#throw_no ⇒ Object
14 |
# File 'lib/rmtools/enumerable/array_iterators.rb', line 14 alias :throw_no :method_missing |
#turn_ccw ⇒ Object
puts [‘123’, ‘456’, ‘789’].turn_ccw 369 258 147
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'ext/rmtools.cpp', line 72
static VALUE rb_ary_turn_ccw(VALUE ary)
{
long elen, alen, i, j;
VALUE tmp, result = 0;
alen = RARRAY_LEN(ary);
if (alen == 0) return rb_ary_dup(ary);
tmp = RARRAY_PTR(ary)[0];
if (TYPE(tmp) == T_STRING) {
elen = RSTRING_LEN(tmp);
result = rb_ary_new2(elen);
for (j=0; j<elen; j++) rb_ary_store(result, j, rb_str_new("", 0));
for (i=0; i<alen; i++) {
if (i) tmp = RARRAY_PTR(ary)[i];
if (elen != RSTRING_LEN(tmp))
rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
RARRAY_LEN(tmp), elen);
for (j=0; j<elen; j++) rb_str_buf_cat(RARRAY_PTR(result)[j], &(RSTRING_PTR(tmp)[elen-1-j]), 1);
}
}
else {
elen = RARRAY_LEN(tmp);
for (j=0; j<elen; j++) rb_ary_store(result, j, rb_ary_new2(alen));
for (i=0; i<alen; i++) {
if (i) tmp = RARRAY_PTR(ary)[i];
if (elen != RARRAY_LEN(tmp))
rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
RARRAY_LEN(tmp), elen);
for (j=0; j<elen; j++) rb_ary_store(RARRAY_PTR(result)[j], i, RARRAY_PTR(tmp)[elen-1-j]);
}
}
return result;
}
|
#turn_cw ⇒ Object
puts [‘123’, ‘456’, ‘789’].turn_cw 147 258 369
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'ext/rmtools.cpp', line 113
static VALUE rb_ary_turn_cw(VALUE ary)
{
long elen, alen, i, j;
VALUE tmp, result = 0;
alen = RARRAY_LEN(ary);
if (alen == 0) return rb_ary_dup(ary);
tmp = RARRAY_PTR(ary)[0];
if (TYPE(tmp) == T_STRING) {
elen = RSTRING_LEN(tmp);
result = rb_ary_new2(elen);
for (j=0; j<elen; j++) rb_ary_store(result, j, rb_str_new("", 0));
for (i=alen-1; i>-1; i--) {
tmp = RARRAY_PTR(ary)[i];
if (elen != RSTRING_LEN(tmp))
rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
RARRAY_LEN(tmp), elen);
for (j=0; j<elen; j++) rb_str_buf_cat(RARRAY_PTR(result)[j], &(RSTRING_PTR(tmp)[j]), 1);
}
}
else {
elen = RARRAY_LEN(tmp);
for (j=0; j<elen; j++) rb_ary_store(result, j, rb_ary_new2(alen));
for (i=0; i<alen; i++) {
if (i) tmp = RARRAY_PTR(ary)[i];
if (elen != RARRAY_LEN(tmp))
rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
RARRAY_LEN(tmp), elen);
for (j=0; j<elen; j++) rb_ary_store(RARRAY_PTR(result)[j], elen-1-i, RARRAY_PTR(tmp)[j]);
}
}
return result;
}
|
#uniq? ⇒ Boolean
uniqs
189 190 191 |
# File 'lib/rmtools/enumerable/array.rb', line 189 def uniq? uniq == self end |
#uniq_by ⇒ Object
Safe version of uniq_by!
229 230 231 232 |
# File 'ext/rmtools.cpp', line 229
static VALUE rb_ary_uniq_by(VALUE ary)
{
return rb_ary_uniq_by_bang(rb_ary_dup(ary));
}
|
#uniq_by! ⇒ Object
Modifies array, throwing all elements not having unique block result a = randarr 10
> [8, 2, 0, 5, 4, 1, 7, 3, 9, 6]
a.uniq_by! {|e| e%2}
> [8, 5]
a
> [8, 5]
Here is implyied that callback block is clean function
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'ext/rmtools.cpp', line 200
static VALUE rb_ary_uniq_by_bang(VALUE ary)
{
if (!rb_block_given_p())
return rb_ary_new4(RARRAY_LEN(ary), RARRAY_PTR(ary));
VALUE hash, res_hash, res, el;
long i, j;
hash = rb_hash_new();
res_hash = rb_hash_new();
for (i=j=0; i<RARRAY_LEN(ary); i++) {
// We store an element itself and so we won't calculate function of it
// other time we'll find it in source. Ruby store function is very fast,
// so we can neglect its runtime even if source array is allready uniq
el = RARRAY_PTR(ary)[i];
if (st_lookup(RHASH_TBL(hash), el, 0)) continue;
res = rb_yield(el);
if (st_lookup(RHASH_TBL(res_hash), res, 0)) continue;
rb_hash_aset(hash, el, Qtrue);
rb_hash_aset(res_hash, res, Qtrue);
rb_ary_store(ary, j++, el);
}
ARY_SET_LEN(ary, j);
return ary;
}
|
#valid_types(pattern_ary) ⇒ Object
43 44 45 46 47 48 49 50 51 |
# File 'lib/rmtools/core/arguments.rb', line 43 def valid_types(pattern_ary) each_with_index.find {|var, i| pattern = pattern_ary[i] if pattern.is Array pattern.find {|j| !(pattern[j] === var[i])} else !(pattern === var[i]) end } end |
#|(ary) ⇒ Object
15 16 17 18 19 20 21 22 |
# File 'lib/rmtools/enumerable/array.rb', line 15 def |(ary) if empty? ary.uniq elsif ary.respond_to? :empty? and ary.empty? dup else union(ary) end end |