Ruby Language
配列
サーチ…
構文
- a = []#配列リテラルを使用する
- a = Array.new#リテラルを使用するのと同じです。
- a = Array.new(5)#値がnilの5つの要素を持つ配列を作成します。
- a = Array.new(5、0)#デフォルト値0の5つの要素を持つ配列を作成します。
#地図
Enumerableによって提供される#map
、各要素のブロックを呼び出して結果を収集することによって配列を作成します。
[1, 2, 3].map { |i| i * 3 }
# => [3, 6, 9]
['1', '2', '3', '4', '5'].map { |i| i.to_i }
# => [1, 2, 3, 4, 5]
元の配列は変更されません。ソース値と同じ順序で変換された値を含む新しい配列が返されます。 map!
元の配列を変更する場合に使用できます。
map
メソッドでは、配列内のすべての要素に対してメソッドを呼び出したり、procを使用したりできます。
# call to_i method on all elements
%w(1 2 3 4 5 6 7 8 9 10).map(&:to_i)
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# using proc (lambda) on all elements
%w(1 2 3 4 5 6 7 8 9 10).map(&->(i){ i.to_i * 2})
# => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
map
はcollect
と同義語です。
リテラルコンストラクタ[]を使用した配列の作成
配列は、角括弧( [
および]
)で要素のリストを囲むことで作成できます。この表記法の配列要素はカンマで区切ります。
array = [1, 2, 3, 4]
配列には、タイプに制限のない任意の組み合わせのオブジェクトを含めることができます。
array = [1, 'b', nil, [3, 4]]
文字列の配列を作成する
文字列の配列は、ルビのパーセント文字列構文を使用して作成できます。
array = %w(one two three four)
これは、配列を以下のように定義することと機能的に同等です。
array = ['one', 'two', 'three', 'four']
%w()
%w{...}
、 %w[...]
または%w<...>
の区切り文字を使用することもできます。
%w!...!
などの任意の英数字以外の区切り文字を使用することもでき%w!...!
、 %w#...#
または%w@...@
。
%W
%w
代わりに%W
を使用して文字列補間を組み込むことができます。次の点を考慮してください。
var = 'hello'
%w(#{var}) # => ["\#{var}"]
%W(#{var}) # => ["hello"]
スペースを\でエスケープすると、複数の単語を解釈することができます。
%w(Colorado California New\ York) # => ["Colorado", "California", "New York"]
シンボルの配列を作成する
array = %i(one two three four)
配列[:one, :two, :three, :four]
作成します。
%i(...)
代わりに、 %i(...)
%i{...}
や%i[...]
や%i!...!
使用することができ%i!...!
また、補間を使用する場合は、 %I
これを行うことができます。
a = 'hello'
b = 'goodbye'
array_one = %I(#{a} #{b} world)
array_two = %i(#{a} #{b} world)
array_one = [:hello, :goodbye, :world]
およびarray_two = [:"\#{a}", :"\#{b}", :world]
array_one = [:hello, :goodbye, :world]
を作成します。
Array :: newで配列を作成する
空の配列( []
)は、Arrayのクラスメソッド、 Array::new
で作成できます。
Array.new
配列の長さを設定するには、数値引数を渡します。
Array.new 3 #=> [nil, nil, nil]
配列にデフォルト値を設定するには、次の2つの方法があります。
- 2番目の引数として不変の値を渡します。
- 現在のインデックスを取得し、変更可能な値を生成するブロックを渡します。
Array.new 3, :x #=> [:x, :x, :x]
Array.new(3) { |i| i.to_s } #=> ["0", "1", "2"]
a = Array.new 3, "X" # Not recommended.
a[1].replace "C" # a => ["C", "C", "C"]
b = Array.new(3) { "X" } # The recommended way.
b[1].replace "C" # b => ["X", "C", "X"]
配列要素の操作
要素の追加:
[1, 2, 3] << 4
# => [1, 2, 3, 4]
[1, 2, 3].push(4)
# => [1, 2, 3, 4]
[1, 2, 3].unshift(4)
# => [4, 1, 2, 3]
[1, 2, 3] << [4, 5]
# => [1, 2, 3, [4, 5]]
要素を削除する:
array = [1, 2, 3, 4]
array.pop
# => 4
array
# => [1, 2, 3]
array = [1, 2, 3, 4]
array.shift
# => 1
array
# => [2, 3, 4]
array = [1, 2, 3, 4]
array.delete(1)
# => 1
array
# => [2, 3, 4]
array = [1,2,3,4,5,6]
array.delete_at(2) // delete from index 2
# => 3
array
# => [1,2,4,5,6]
array = [1, 2, 2, 2, 3]
array - [2]
# => [1, 3] # removed all the 2s
array - [2, 3, 4]
# => [1] # the 4 did nothing
配列の結合:
[1, 2, 3] + [4, 5, 6]
# => [1, 2, 3, 4, 5, 6]
[1, 2, 3].concat([4, 5, 6])
# => [1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6] - [2, 3]
# => [1, 4, 5, 6]
[1, 2, 3] | [2, 3, 4]
# => [1, 2, 3, 4]
[1, 2, 3] & [3, 4]
# => [3]
また、配列を乗算することもできます。
[1, 2, 3] * 2
# => [1, 2, 3, 1, 2, 3]
配列の組合、交差点と相違点
x = [5, 5, 1, 3]
y = [5, 2, 4, 3]
Union( |
)には、両方の配列の要素が含まれ、重複が削除されます。
x | y
=> [5, 1, 3, 2, 4]
交点( &
)には、第1配列と第2配列の両方に存在する要素が含まれます。
x & y
=> [5, 3]
差( -
)には、最初の配列に存在し、2番目の配列には存在しない要素が含まれます。
x - y
=> [1]
配列のフィルタリング
特定の条件を満たす配列の要素に対してのみ操作したい場合があります。
選択
特定の条件に一致する要素を返します。
array = [1, 2, 3, 4, 5, 6]
array.select { |number| number > 3 } # => [4, 5, 6]
拒否
特定の条件に合致しない要素を返します。
array = [1, 2, 3, 4, 5, 6]
array.reject { |number| number > 3 } # => [1, 2, 3]
#select
と#reject
両方が配列を返すので、それらをチェーンすることができます:
array = [1, 2, 3, 4, 5, 6]
array.select { |number| number > 3 }.reject { |number| number < 5 }
# => [5, 6]
注入、減らす
注入と還元は同じものの異なる名前です。他の言語では、これらの機能は折り畳み(foldlやfoldrのような)と呼ばれることがよくあります。これらのメソッドは、すべてのEnumerableオブジェクトで使用できます。
Injectは2つの引数関数をとり、Arrayの要素のすべてのペアに適用します。
配列[1, 2, 3]
に対して、開始値とブロックを指定することによって、これらのすべてを開始値0で追加することができます。
[1,2,3].reduce(0) {|a,b| a + b} # => 6
ここでは、関数に開始値と、すべての値を加算するというブロックを渡します。ブロックは最初に0
をa
として実行し、 1
をb
として実行し、その結果を次のa
として2番目の値2
1
を加算します。その後、我々は、(その結果を取る3
(も)し、リストの最後の要素にそれを上の追加3
(私たちの結果を与える) 6
)。
最初の引数を省略すると、 a
がリストの最初の要素になるので、上記の例は次のようになります。
[1,2,3].reduce {|a,b| a + b} # => 6
さらに、関数を持つブロックを渡すのではなく、名前付き関数をシンボルとして開始値で渡すことも、渡すこともできます。これにより、上記の例は次のように書くことができます:
[1,2,3].reduce(0, :+) # => 6
開始値を省略するか、
[1,2,3].reduce(:+) # => 6
要素へのアクセス
インデックスの配列を使用して配列の要素にアクセスできます。配列インデックス番号は0
から始まり0
。
%w(a b c)[0] # => 'a'
%w(a b c)[1] # => 'b'
レンジを使用して配列をトリミングすることができます
%w(a b c d)[1..2] # => ['b', 'c'] (indices from 1 to 2, including the 2)
%w(a b c d)[1...2] # => ['b'] (indices from 1 to 2, excluding the 2)
これは新しい配列を返しますが、元の配列には影響しません。 Rubyは負のインデックスの使用もサポートしています。
%w(a b c)[-1] # => 'c'
%w(a b c)[-2] # => 'b'
負のインデックスと正のインデックスを組み合わせることもできます
%w(a b c d e)[1...-1] # => ['b', 'c', 'd']
その他の便利な方法
配列の最初の要素にアクセスするには、 first
を使用します。
[1, 2, 3, 4].first # => 1
または、配列に返された最初のn
要素にアクセスするためのfirst(n)
[1, 2, 3, 4].first(2) # => [1, 2]
last
とlast(n)
同様です。
[1, 2, 3, 4].last # => 4
[1, 2, 3, 4].last(2) # => [3, 4]
sample
を使用して、配列内のランダムな要素にアクセスします。
[1, 2, 3, 4].sample # => 3
[1, 2, 3, 4].sample # => 1
またはsample(n)
:
[1, 2, 3, 4].sample(2) # => [2, 1]
[1, 2, 3, 4].sample(2) # => [3, 4]
2次元配列
Array::new
コンストラクタを使用すると、指定されたサイズの配列とそのスロットの新しい配列を初期化できます。内部配列には、サイズと初期値を与えることもできます。
たとえば、3x4の0の配列を作成するには:
array = Array.new(3) { Array.new(4) { 0 } }
上記で生成された配列は、 p
:
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
次のような要素を読み書きすることができます:
x = array[0][1]
array[2][3] = 2
配列とスプラット(*)演算子
*
演算子を使用すると、変数と配列を個々の引数としてメソッドに渡すことができます。
これは、配列内に単一のオブジェクトをラップするために使用されていない場合に使用できます。
def wrap_in_array(value)
[*value]
end
wrap_in_array(1)
#> [1]
wrap_in_array([1, 2, 3])
#> [1, 2, 3]
wrap_in_array(nil)
#> []
上記の例では、 wrap_in_array
メソッドは1つの引数value
受け入れvalue
。
value
がArray
場合、その要素は展開され、それらの要素を含む新しい配列が作成されます。
value
が単一のオブジェクトである場合、その単一のオブジェクトを含む新しい配列が作成されます。
value
がnil
場合、空の配列が返されます。
スプラット演算子は、場合によってはメソッドの引数として使用すると特に便利です。たとえば、 nil
、単一の値と配列を一貫した方法で処理することができます。
def list(*values)
values.each do |value|
# do something with value
puts value
end
end
list(100)
#> 100
list([100, 200])
#> 100
#> 200
list(nil)
# nothing is outputted
分解
任意の配列は、その要素を複数の変数に割り当てることによって、迅速に分解できます。簡単な例:
arr = [1, 2, 3]
# ---
a = arr[0]
b = arr[1]
c = arr[2]
# --- or, the same
a, b, c = arr
変数にスプラット演算子( *
)を付けると、他の変数によって捕捉されていないすべての要素の配列がその配列に挿入されます。何も残っていなければ、空の配列が割り当てられます。 1つの割り当てで使用できるスプラットは1つだけです。
a, *b = arr # a = 1; b = [2, 3]
a, *b, c = arr # a = 1; b = [2]; c = 3
a, b, c, *d = arr # a = 1; b = 2; c = 3; d = []
a, *b, *c = arr # SyntaxError: unexpected *
分解は安全でエラーを発生させることはありません。範囲外のインデックスにアクセスするときに、 []
演算子の動作に一致する十分な要素がないところにはnil
が割り当てられます。
arr[9000] # => nil
a, b, c, d = arr # a = 1; b = 2; c = 3; d = nil
分解は、割り当てられているオブジェクトに対してto_ary
暗黙的にto_ary
うとします。あなたのタイプにこのメソッドを実装すると、それを分解する能力が得られます:
class Foo
def to_ary
[1, 2]
end
end
a, b = Foo.new # a = 1; b = 2
分解されているオブジェクトがrespond_to?
ない場合はrespond_to?
to_ary
は、単一要素の配列として扱われます。
1.respond_to?(:to_ary) # => false
a, b = 1 # a = 1; b = nil
分解は、そうでなければ単一の要素である代わりに、 ()
区切られた分解式を使用してネストすることもできます。
arr = [1, [2, 3, 4], 5, 6]
a, (b, *c), *d = arr # a = 1; b = 2; c = [3, 4]; d = [5, 6]
# ^^^^^
これは実質的にスプラットの反対です。
実際、分解式は()
で区切ることができます。しかし、第1レベルの分解は任意である。
a, b = [1, 2]
(a, b) = [1, 2] # the same thing
エッジケース: 単一の識別子は、外側またはネストされたものであれば、非構造化パターンとして使用できません。
(a) = [1] # SyntaxError
a, (b) = [1, [2]] # SyntaxError
destructuring式に配列リテラルを代入する場合、outer []
は省略できます:
a, b = [1, 2]
a, b = 1, 2 # exactly the same
これは並列割当てと呼ばれますが、フードの下で同じ分解を使用します。これは、追加の一時変数を使用せずに変数の値を交換する場合に特に便利です:
t = a; a = b; b = t # an obvious way
a, b = b, a # an idiomatic way
(a, b) = [b, a] # ...and how it works
割り当ての右側を構築するときに値が取得されるため、ソースと宛先と同じ変数を使用することは比較的安全です。
多次元配列を1次元(平坦な)配列に変換する
[1, 2, [[3, 4], [5]], 6].flatten # => [1, 2, 3, 4, 5, 6]
多次元配列を持ち、それを単純な (つまり1次元の)配列にする必要がある場合は#flatten
メソッドを使用できます。
一意の配列要素を取得する
繰り返しを避ける配列要素を読み込む必要がある場合は、 #uniq
メソッドを使用します:
a = [1, 1, 2, 3, 4, 4, 5]
a.uniq
#=> [1, 2, 3, 4, 5]
代わりに、配列から重複した要素をすべて削除する場合は、 #uniq!
使用することができます#uniq!
方法:
a = [1, 1, 2, 3, 4, 4, 5]
a.uniq!
#=> [1, 2, 3, 4, 5]
出力は同じですが、 #uniq!
新しい配列も格納されます:
a = [1, 1, 2, 3, 4, 4, 5]
a.uniq
#=> [1, 2, 3, 4, 5]
a
#=> [1, 1, 2, 3, 4, 4, 5]
a = [1, 1, 2, 3, 4, 4, 5]
a.uniq!
#=> [1, 2, 3, 4, 5]
a
#=> [1, 2, 3, 4, 5]
配列のすべての組み合わせ/置換を取得する
permutation
方法は、ブロックで呼び出されると、数の集合のすべての順序付けられたシーケンスからなる2次元配列を生成する。
このメソッドがブロックなしで呼び出されると、 enumerator
が返さenumerator
。配列に変換するには、 to_a
メソッドを呼び出します。
例 | 結果 |
---|---|
[1,2,3].permutation | #<Enumerator: [1,2,3]:permutation |
[1,2,3].permutation.to_a | [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] |
[1,2,3].permutation(2).to_a | [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]] |
[1,2,3].permutation(4).to_a | [] - >長さ4の順列なし |
一方、ブロックで呼び出されたときのcombination
方法は、数値集合のすべてのシーケンスからなる2次元配列を生成します。順列とは異なり、順序は組み合わせて無視されます。たとえば、 [1,2,3]
は[3,2,1]
と同じです[3,2,1]
例 | 結果 |
---|---|
[1,2,3].combination(1) | #<Enumerator: [1,2,3]:combination |
[1,2,3].combination(1).to_a | [[1],[2],[3]] |
[1,2,3].combination(3).to_a | [[1,2,3]] |
[1,2,3].combination(4).to_a | [] - >長さ4の組み合わせはありません |
組み合わせメソッドを単独で呼び出すと、列挙子が生成されます。配列を取得するには、 to_a
メソッドを呼び出します。
repeated_combination
とrepeated_permutation
同じ要素が複数回繰り返すことができる以外方法は、類似しています。
例えば、配列[1,1]
、 [1,3,3,1]
、 [3,3,3]
は、規則的な組み合わせおよび順列では有効ではない。
例 | #コンボ |
---|---|
[1,2,3].combination(3).to_a.length | 1 |
[1,2,3].repeated_combination(3).to_a.length | 6 |
[1,2,3,4,5].combination(5).to_a.length | 1 |
[1,2,3].repeated_combination(5).to_a.length | 126 |
連続する数字または文字の配列を作成する
これは、 Range
オブジェクトのEnumerable#to_a
を呼び出すことで簡単に実行できます。
(1..10).to_a #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
(a..b)
は、aとbの間のすべての数値を含むことを意味します。最後の番号を除外するには、 a...b
a_range = 1...5
a_range.to_a #=> [1, 2, 3, 4]
または
('a'..'f').to_a #=> ["a", "b", "c", "d", "e", "f"]
('a'...'f').to_a #=> ["a", "b", "c", "d", "e"]
配列を作成するための便利なショートカットは[*a..b]
[*1..10] #=> [1,2,3,4,5,6,7,8,9,10]
[*'a'..'f'] #=> ["a", "b", "c", "d", "e", "f"]
#compactで配列からすべてのnil要素を削除する
アレイは、1つまたは複数の持つことが起こった場合nil
要素を、これらを削除する必要があり、 Array#compact
またはArray#compact!
以下のような方法を用いることができる。
array = [ 1, nil, 'hello', nil, '5', 33]
array.compact # => [ 1, 'hello', '5', 33]
#notice that the method returns a new copy of the array with nil removed,
#without affecting the original
array = [ 1, nil, 'hello', nil, '5', 33]
#If you need the original array modified, you can either reassign it
array = array.compact # => [ 1, 'hello', '5', 33]
array = [ 1, 'hello', '5', 33]
#Or you can use the much more elegant 'bang' version of the method
array = [ 1, nil, 'hello', nil, '5', 33]
array.compact # => [ 1, 'hello', '5', 33]
array = [ 1, 'hello', '5', 33]
最後に、 #compact
または#compact!
nil
要素のない配列で呼び出された場合、これらはnilを返します。
array = [ 'foo', 4, 'life']
array.compact # => nil
array.compact! # => nil
数値の配列を作成する
数値の配列を作成する通常の方法:
numbers = [1, 2, 3, 4, 5]
Rangeオブジェクトは、数値の配列を作成するために幅広く使用できます。
numbers = Array(1..10) # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
numbers = (1..10).to_a # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#step
および#map
メソッドを使用すると、数値の範囲に条件を課すことができます。
odd_numbers = (1..10).step(2).to_a # => [1, 3, 5, 7, 9]
even_numbers = 2.step(10, 2).to_a # => [2, 4, 6, 8, 10]
squared_numbers = (1..10).map { |number| number * number } # => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
上記の方法はすべて数字を熱心に読み込みます。遅れてロードする必要がある場合:
number_generator = (1..100).lazy # => #<Enumerator::Lazy: 1..100>
number_generator.first(10) # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
任意のオブジェクトから配列にキャスト
任意のオブジェクトからArrayを取得するには、 Kernel#Array
使用します。
次はその例です。
Array('something') #=> ["something"]
Array([2, 1, 5]) #=> [2, 1, 5]
Array(1) #=> [1]
Array(2..4) #=> [2, 3, 4]
Array([]) #=> []
Array(nil) #=> []
たとえば、次のコードからjoin_as_string
メソッドを置き換えることができます
def join_as_string(arg)
if arg.instance_of?(Array)
arg.join(',')
elsif arg.instance_of?(Range)
arg.to_a.join(',')
else
arg.to_s
end
end
join_as_string('something') #=> "something"
join_as_string([2, 1, 5]) #=> "2,1,5"
join_as_string(1) #=> "1"
join_as_string(2..4) #=> "2,3,4"
join_as_string([]) #=> ""
join_as_string(nil) #=> ""
次のコードに追加します。
def join_as_string(arg)
Array(arg).join(',')
end