まとめたものダウンロード
添字付きcollect。collect と each_index を組み合わせたもの。
module Enumerable
def collect_with_index
r = []
each_index do |i|
r << yield(i, self[i])
end
r
end
end
各項目を評価した結果が真のものの評価結果を返す。
perlのmapに近い挙動のメソッド
名称を変えました。
module Enumerable
def collect_if
collect do |x|
yield x
end.select do |x|
x
end
end
alias :selective_collect :collect_if
end
Array
listup
上のEnumerable#collect_with_indexをそのまま使ったもの。
書式をパラメータとして与えることが可能。
ソース
class Array
def listup(fmt = "%d %s\n")
collect_with_index do |i, v|
printf fmt, i, v
end
end
end
each_n
n個づつのeach
ソース
class Array
def each_n(n)
tmp = []
each_index do |i|
tmp << self[i]
if i % n == n - 1
yield *tmp
tmp = []
end
end
yield *tmp if tmp.size > 0
end
end
car, cdr, cadr, cdar, ...
lispのcar, cdr, cadr ...
ソース
class Array
def method_missing(msgid, *arg)
if /^c([ad]+)r$/ === msgid.to_s
r = dup
$1.scan(/[ad]/).reverse.each do |ad|
r = if ad == 'a' then r[0] else r[1..-1] end
end
r
else
super msgid, arg
end
end
end
to_h
ArrayからHashを作る
ソース
class Array
def to_h
Hash[*self]
end
end
proc_by
n個毎に処理を行う
ソース
class Array
def proc_by(n, offset = 0)
@result = self[0, offset]
((length + n - 1 - offset) / n).times do |i|
@result += self[i * n + offset, n - 1]
@result += yield(self[i * n + n - 1 + offset]).to_a
end
@result
end
end
divide_by
n個毎に分割する
nがArrayの場合、その数に従って分割。(入れ子のArrayはflattenされる)
ソース
class Array
def rotate_left
s = shift
push s
s
end
def rotate_right
s = pop
unshift s
s
end
def divide_by(*order)
@result = []
n = order.dup.flatten
n = n[0] if n.is_a?(Array) && n.length == 1
if n.is_a? Array
ptr = 0
while ptr < length
s = n.rotate_left
@result += [self[ptr, s]]
ptr += s
end
else
((length + n - 1) / n).times do |i|
@result += [self[i * n, n]]
end
end
@result
end
end
grouping
各項がそれぞれArrayであるとして、共通部分を持つ項同士での和集合を作る。
例) [[1, 2], [2, 3], [4, 5]] -> [[1, 2, 3], [4, 5]]
ソース
class Array
def grouping
r = []
each do |x|
found = false
r.each do |y|
if (x & y).size > 0
y.replace(y | x)
found = true
break
end
end
r += [x] unless found
end
r
end
end
cap
配列の配列のすべての項の積集合を求める。
例) [[1, 2], [2, 3]] -> [2]
ソース
class Array
def cap
r = self[0]
each do |x|
r &= x
end
r
end
end
cup
配列の配列のすべての項の和集合を求める。
例) [[1, 2], [2, 3]] -> [1, 2, 3]
ソース
class Array
def cup
r = self[0]
each do |x|
r |= x
end
r
end
end
assoc_all
配列の配列のを検索し、第1要素がkeyと等しいすべての配列を配列で返す。
例) [[1, 2], [1, 3], [2, 3]] -> [[1, 2], [1, 3]]
ソース
class Array
def assoc_all(key)
r = []
each do |x|
r << x if x[0] == key
end
r
end
end
rassoc_all
配列の配列のを検索し、第2要素がvalueと等しいすべての配列を配列で返す。
例) [[1, 2], [1, 3], [2, 3]] -> [[1, 3], [2, 3]]
ソース
class Array
def rassoc_all(value)
r = []
each do |x|
r << x if x[1] == value
end
r
end
end
each_x
複数の配列から順に値を取り出す。各配列の要素数が異なる場合、最後の値を使う。先頭から繰り返すのいずれかが選択可能。
Arrayの添字が範囲外だった場合にnilを返さないクラス2つも以下に含みます。(LastArray:最後の値を使う, RepeatArray:先頭から繰り返す)
破壊的なメソッドを使うことが可能ですが要素数が同じでない場合、再度破壊的メソッドが使われますので注意が必要です。
例)
a = RepeatArray.new([1, 2, 3])
10.times do |n| p [n, a[n]] end
[0, 1]
[1, 2]
[2, 3]
[3, 1]
[4, 2]
[5, 3]
[6, 1]
[7, 2]
[8, 3]
[9, 1]
a = LastArray.new([1, 2, 3])
10.times do |n| p [n, a[n]] end
[0, 1]
[1, 2]
[2, 3]
[3, 3]
[4, 3]
[5, 3]
[6, 3]
[7, 3]
[8, 3]
[9, 3]
ary = [[1, 2, 3, 4, 5], ['A', 'B', 'C'], [1.2, Dir]]
ary.each_x(:FILL_LAST) do |a, b, c| p [a, b, c] end
[1, "A", 1.2]
[2, "B", Dir]
[3, "C", Dir]
[4, "C", Dir]
[5, "C", Dir]
ary.each_x(:FILL_REPEAT) do |a, b, c| p [a, b, c] end
[1, "A", 1.2]
[2, "B", Dir]
[3, "C", 1.2]
[4, "A", Dir]
[5, "B", 1.2]
ソース
require 'delegate'
class RepeatArray<DelegateClass(Array)
def initialize(value)
super
end
alias get_a []
def [](idx)
get_a(idx % size)
end
alias set_a []=
def []=(idx, value)
set_a(idx % @value.size, value)
end
end
class LastArray<DelegateClass(Array)
def initialize(value)
super
end
alias get_a []
def [](idx)
if idx >= size
get_a(size - 1)
else
get_a(idx)
end
end
alias set_a []=
def []=(idx, value)
if idx >= size
set_a(size - 1, value)
else
set_a(idx, value)
end
end
end
class Array
FILL_REPEAT = :FILL_REPEAT
FILL_LAST = :FILL_LAST
def each_x(opt = :FILL_LAST)
min = max = self[0].size
accessor = collect do |i|
min = i.size if i.size < min
max = i.size if i.size > max
if opt == :FILL_LAST
SimpleDelegater.new(LastArray.new(i))
else
SimpleDelegater.new(RepeatArray.new(i))
end
end
(0...max).each do |i|
tmp = accessor.collect do |x| x[i] end
yield tmp
end
end
end
back