Array 클래스
Array 클래스
Array는 정수 인덱스로 접근하는 순서 있는 객체 컬렉션이에요. 요소(element)라고 부르는 각 원소에는 어떤 객체든(심지어 다른 배열도) 들어갈 수 있고, 서로 다른 타입의 객체를 한 배열에 담을 수 있어요.
출처: Ruby 3.3 API
본문
배열 인덱스 (Array Indexes)
배열 인덱스는 C나 Java처럼 0부터 시작해요.
- 양수 인덱스는 첫 요소로부터의 오프셋이에요. 인덱스 0은 첫 요소, 1은 두 번째 요소를 가리켜요.
- 음수 인덱스는 끝에서부터 거꾸로 센 오프셋이에요. 인덱스 -1은 마지막 요소, -2는 마지막에서 두 번째 요소예요.
음이 아닌 인덱스는 배열 크기보다 작을 때만 범위 안이에요. 3요소 배열이라면 인덱스 02는 유효하고 3은 범위를 벗어나요. 음수 인덱스는 절댓값이 배열 크기보다 크지 않을 때만 유효해요. 3요소 배열에서 -1-3은 유효하고 -4는 범위를 벗어나요.
배열의 실질 인덱스는 항상 정수지만, Array 클래스 안팎의 일부 메서드는 정수로 변환 가능한 객체를 인자로 받기도 해요.
배열 생성 (Creating Arrays)
배열 리터럴:
[1, 'one', :one, [2, 'two', :two]]
%w[foo bar baz] # => ["foo", "bar", "baz"]
%w[1 % *] # => ["1", "%", "*"]
%i[foo bar baz] # => [:foo, :bar, :baz]
%i[1 % *] # => [:"1", :%, :*]
Kernel#Array 메서드:
Array(["a", "b"]) # => ["a", "b"]
Array(1..5) # => [1, 2, 3, 4, 5]
Array(key: :value) # => [[:key, :value]]
Array(nil) # => []
Array(1) # => [1]
Array({:a => "a", :b => "b"}) # => [[:a, "a"], [:b, "b"]]
Array.new 메서드:
Array.new # => []
Array.new(3) # => [nil, nil, nil]
Array.new(4) {Hash.new} # => [{}, {}, {}, {}]
Array.new(3, true) # => [true, true, true]
블록을 주면 각 요소를 블록의 반환값으로 채워요:
Array.new(4) {|i| i.to_s } # => ["0", "1", "2", "3"]
다차원 배열 만들기:
Array.new(3) {Array.new(3)}
# => [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
주의할 점이 있어요. 마지막 예시처럼 기본값을 넣으면 배열이 같은 객체에 대한 참조로 채워져요. 이 방식은 그 객체가 심볼·숫자·nil·true·false처럼 본질적으로 변경 불가능한(immutable) 값일 때만 권장해요. 해시·문자열·다른 배열 같은 변경 가능한 객체를 넣을 땐 블록을 쓰는 게 안전해요.
코어와 표준 라이브러리 여러 곳에서 to_a 인스턴스 메서드를 제공해 객체를 배열로 변환할 수 있어요 — ARGF#to_a, Array#to_a, Enumerable#to_a, Hash#to_a, MatchData#to_a, Range#to_a, Set#to_a, Time#to_a 등이 대표적이에요.
요소 접근 (Accessing Elements)
Array#[] 메서드로 요소를 꺼낼 수 있어요. 단일 정수 인덱스, (시작, 길이) 인자 쌍, 또는 범위(range)를 받을 수 있어요. 음수 인덱스는 끝에서부터 세며 -1이 마지막 요소예요.
arr = [1, 2, 3, 4, 5, 6]
arr[2] #=> 3
arr[100] #=> nil
arr[-3] #=> 4
arr[2, 3] #=> [3, 4, 5]
arr[1..4] #=> [2, 3, 4, 5]
arr[1..-3] #=> [2, 3, 4]
at메서드로도 특정 요소에 접근할 수 있어요.arr.at(0) #=> 1slice는Array#[]와 똑같이 동작해요.- 인덱스가 배열 범위를 벗어날 때 에러를 내고 싶거나, 그때 기본값을 주고 싶으면
fetch를 써요.
arr = ['a', 'b', 'c', 'd', 'e', 'f']
arr.fetch(100) #=> IndexError: index 100 outside of array bounds: -6...6
arr.fetch(100, "oops") #=> "oops"
first와last는 각각 첫·마지막 요소를 돌려줘요.take(n)은 앞의 n개 요소를 돌려주고,drop(n)은 n개를 버린 나머지를 돌려줘요.
arr.first #=> 1
arr.last #=> 6
arr.take(3) #=> [1, 2, 3]
arr.drop(3) #=> [4, 5, 6]
배열에 대한 정보 (Obtaining Information)
배열은 항상 자기 길이를 관리해요. 요소 수를 묻는 데는 length, count, size를 써요. 비었는지는 empty?, 특정 항목이 들어 있는지는 include?로 확인할 수 있어요.
browsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'IE']
browsers.length #=> 5
browsers.count #=> 5
browsers.empty? #=> false
browsers.include?('Konqueror') #=> false
배열에 항목 추가 (Adding Items)
끝에 항목을 추가하려면 push나 <<를 써요.
arr = [1, 2, 3, 4]
arr.push(5) #=> [1, 2, 3, 4, 5]
arr << 6 #=> [1, 2, 3, 4, 5, 6]
시작 부분에 추가하려면 unshift를 써요.
arr = [1, 2, 3, 4]
arr.unshift(0) #=> [0, 1, 2, 3, 4]
중간에 삽입하려면 insert를 써요.
arr = [1, 2, 3, 4]
arr.insert(2, "apple") #=> [1, 2, "apple", 3, 4]
arr.insert(2, "pawpaw", "coconut") #=> [1, 2, "pawpaw", "coconut", "apple", 3, 4]
배열에서 항목 제거 (Removing Items)
pop은 끝의 항목을, shift는 앞의 항목을 꺼내면서 제거해요.
arr = [1, 2, 3, 4, 5, 6]
arr.pop #=> 6
arr #=> [1, 2, 3, 4, 5]
arr.shift #=> 1
arr #=> [2, 3, 4, 5]
delete_at은 인덱스로 특정 요소를, delete는 값으로 일치하는 요소를 제거해요.
arr = [1, 2, 3, 4, 5, 6]
arr.delete_at(2) #=> 3
arr #=> [1, 2, 4, 5, 6]
arr.delete(4) #=> 4
arr #=> [1, 2, 5, 6]
메서드 카테고리 요약
아래는 Array를 다루는 관점별 메서드 정리예요.
- 비파괴 선택(Non-destructive Selection):
reject,select,filter,drop_while,take_while,uniq,compact,flatten등 - 파괴적 선택(Destructive Selection):
reject!,select!,filter!,uniq!,compact!,flatten!,slice!,keep_if,delete_if등 - 생성(Creating):
[],new,try_convert - 조회(Querying):
length,size,count,empty?,include?,any?,all?,none?,one?,index,rindex,hash등 - 비교(Comparing):
==,eql?,<=> - 가져오기(Fetching):
[],at,fetch,first,last,take,drop,values_at,slice,dig,assoc,rassoc등 - 할당(Assigning):
[]=,insert,fill,initialize_copy,replace,push,<<,append,unshift,prepend,concat - 삭제(Deleting):
clear,delete,delete_at,delete_if,keep_if,pop,shift,slice! - 결합(Combining):
+,-,&,|,*,difference,union,intersection,intersect?,product,zip,concat,sum,join등 - 반복(Iterating):
each,each_index,reverse_each,cycle,map/collect,select,reject,filter,keep_if,delete_if,bsearch,bsearch_index,sort,sort_by!등 - 변환(Converting):
to_a,to_ary,to_h,to_s,inspect,pack,shelljoin,transpose,flatten등 - 기타(Other):
combination,permutation,repeated_combination,repeated_permutation,sample,shuffle,rotate,sort,sort!,min,max,minmax,abbrev등
클래스 메서드 (Public Class Methods)
→ new_array
인자들을 요소로 하는 새 배열을 만들어요. 각 인자는 배열이 아니라면 원소로, 배열이라면 그 요소들이 해체(flatten)되어 들어가요.
Array[] #=> []
Array.[](1, 2, 3) #=> [1, 2, 3]
Array[1, 2, 3] #=> [1, 2, 3]
Array[1, [2, 3]] #=> [1, 2, 3]
new → new_empty_array / new(array) → new_array
new는 빈 새 배열을 만들고, new(array)는 인자 배열의 요소들로 새 배열을 만들어요 (shallow copy).
Array.new #=> []
Array.new([1, 2, 3]) #=> [1, 2, 3]
new(size) → new_array / new(size, default_value) → new_array / new(size) {|index| ... } → new_array
new(size)는 size개 만큼의 nil로 채워진 배열을 만들어요. new(size, default_value)는 default_value로 채우고, 블록을 주면 각 인덱스를 블록에 넘겨 그 반환값으로 채워요.
Array.new(3) #=> [nil, nil, nil]
Array.new(3, true) #=> [true, true, true]
Array.new(3) {|i| i*2 } #=> [0, 2, 4]
size가 양의 정수가 아니면 빈 배열을 돌려줘요.
try_convert(object) → object, new_array, or nil
object에 to_ary 메서드가 없으면 nil을, to_ary가 배열을 반환하면 그 배열을 돌려줘요. to_ary가 배열이 아닌 값을 반환하면 TypeError를 던져요. 인자가 nil이면 nil이에요.
인스턴스 메서드 (Public Instance Methods)
array & other_array → new_array
두 배열의 교집합을 새 배열로 돌려줘요. 결과에는 other_array에도 있는 원소들이 들어가요. 중복은 제거되고, 순서는 원본 배열 기준이에요.
[1, 1, 3, 5] & [1, 2, 3] #=> [1, 3]
array * n → new_array
배열을 n번 반복한 새 배열을 돌려줘요.
[1, 2, 3] * 2 #=> [1, 2, 3, 1, 2, 3]
array * string_separator → new_string
요소들을 string_separator로 이어 붙인 하나의 문자열을 돌려줘요. Array#join과 같아요.
[1, 2, 3] * ", " #=> "1, 2, 3"
array + other_array → new_array
두 배열을 합친 새 배열을 돌려줘요. 원래 배열들은 바뀌지 않아요.
[1, 2] + [3, 4] #=> [1, 2, 3, 4]
array - other_array → new_array
other_array에 있는 요소를 뺀 새 배열을 돌려줘요.
[1, 1, 2, 2, 3, 3, 4, 5] - [1, 2, 4] #=> [3, 3, 5]
array << object → self
object를 배열 끝에 추가하고 self를 돌려줘요. push의 별칭이에요.
a = [1, 2]; a << 3; a #=> [1, 2, 3]
array <=> other_array → -1, 0, or 1
배열을 비교해요. 이 메서드는 각 요소를 순서대로 비교해서 첫 번째로 다르게 나오는 요소쌍의 결과로 결정돼요. 결과가 nil인 요소쌍이 나오면 nil을 돌려줘요. 모든 요소가 같으면 길이로 비교해요. other_array가 배열이 아니면 nil이에요.
array == other_array → true or false
같은 길이이고 모든 요소가 순서대로 같은지(==) 비교해요.
["a", "c"] == ["a", "c", 7] #=> false
["a", "c", 7] == ["a", "c", 7] #=> true
array[index] → object or nil / array[start, length] → object or nil / array[range] → object or nil / array[aseq] → object or nil
요소를 돌려줘요. index 형태는 해당 인덱스의 요소(범위 밖이면 nil), start, length는 시작 위치부터 length 개, range는 범위에 해당하는 새 배열(또는 첨자 aseq), beginless/endless 범위도 지원해요.
a = ["foo", "bar", "baz"]
a[1] #=> "bar"
a[-2] #=> "bar"
a[1, 2] #=> ["bar", "baz"]
a[1..-1] #=> ["bar", "baz"]
array[index] = object → object / array[start, length] = object → object / array[range] = object → object
index 위치에 object를 넣어요. start, length는 해당 구간을 object(배열이면 한 요소씩)로 대체해요. range도 마찬가지로 대체해요. 반환값은 object예요.
abbrev(pattern = nil) → new_hash
require 'abbrev'가 필요해요. Abbrev.abbrev(self, pattern)과 동일하게 배열을 축약 이름 집합으로 변환해요.
all? → true or false / all? {|element| ... } / all?(obj)
배열이 비어 있으면 true를 돌려줘요. 블록을 주면 모든 요소가 블록 조건을 만족하는지, obj를 주면 모든 요소가 obj == element인지 확인해요.
any? → true or false / any? {|element| ... } / any?(obj)
배열에 조건을 만족하는 요소가 하나라도 있는지 확인해요. 비어 있으면 false, 블록 없이는 요소가 truthy인 것이 있는지 확인해요.
append / prepend
append는 push의 별칭, prepend는 unshift의 별칭이에요.
assoc(obj) → found_array or nil
각 요소가 배열일 때, 첫 요소가 obj == element[0]인 첫 배열을 찾아 돌려줘요.
s1 = ["colors", "red", "blue", "green"]
[ s1 ].assoc("colors") #=> ["colors", "red", "blue", "green"]
[ s1 ].assoc("letters") #=> nil
at(index) → object
array[index]와 동일해요. index의 요소를 돌려줘요.
arr.at(0) #=> 1
bsearch {|element| ... } → object / bsearch → new_enumerator
이진 탐색으로 블록 조건에 맞는 요소를 찾아요. "find-minimum" 모드와 "find-any" 모드 두 가지가 있어요. 배열은 미리 정렬돼 있어야 해요.
bsearch_index {|element| ... } → integer or nil / bsearch_index → new_enumerator
bsearch처럼 탐색하되, 요소 대신 그 인덱스를 돌려줘요.
clear → self
모든 요소를 제거하고 빈 배열로 만들어요.
a = [1, 2, 3]; a.clear; a #=> []
collect / collect!
map과 map!의 별칭이에요. 각 요소를 블록 결과로 변환한 새 배열을 돌려주거나(collect), 파괴적으로 바꿔요(collect!).
combination(n) {|element| ... } → self / combination(n) → new_enumerator
배열에서 n개를 고르는 모든 조합을 생성해 블록에 넘겨요. 블록 없이는 열거자(enumerator)로 동작해요.
a = [1, 2, 3, 4]
a.combination(2).to_a #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
compact → new_array / compact! → self or nil
nil 요소를 제거한 새 배열을 돌려주거나(compact), 파괴적으로 제거해요(compact!). nil이 없으면 compact!는 nil을 돌려줘요.
a = ["foo", 0, nil, "bar", nil]
a.compact #=> ["foo", 0, "bar"]
concat(*other_arrays) → self
self 끝에 other_arrays의 모든 요소를 추가하고 self를 돌려줘요.
["a", "b"].concat(["c", "d"]) #=> ["a", "b", "c", "d"]
count → an_integer / count(obj) → an_integer / count {|element| ... } → an_integer
인자 없이 블록 없이 호출하면 요소 수를, obj를 주면 obj와 같은 요소 수를, 블록을 주면 블록이 true인 요소 수를 돌려줘요.
cycle {|element| ... } → nil / cycle(count) {|element| ... } → nil / cycle → new_enumerator / cycle(count) → new_enumerator
배열 요소를 계속 순환하며 블록에 넘겨요. 블록이 break하면 중단돼요. count의 절댓값만큼 반복하고, 블록 없이는 열거자로 동작해요.
delete(obj) → deleted_object / delete(obj) {|nosuch| ... } → deleted_object or block_return
obj와 같은 모든 요소를 제거하고 그 값을 돌려줘요. 없으면 블록 있으면 블록 결과를, 없으면 nil을 돌려줘요.
a = [1, 2, 3, 2, 1]
a.delete(2) #=> 2
a #=> [1, 3, 1]
delete_at(index) → deleted_object or nil
index 위치의 요소를 제거하고 돌려줘요. 범위 밖이면 nil이에요.
a = %w[ant bat cat dog]
a.delete_at(2) #=> "cat"
a #=> ["ant", "bat", "dog"]
delete_if {|element| ... } → self / delete_if → Enumerator
블록 조건이 true인 모든 요소를 제거해요. 블록 없이는 열거자로 동작해요.
a = [0, 1, 2, 3, 4, 5]
a.delete_if {|x| x > 2 } #=> [0, 1, 2]
difference(*other_arrays) → new_array
other_arrays 어느 곳에든 있는 요소를 제외한 새 배열을 돌려줘요. -와 비슷하지만 여러 배열을 한 번에 빼요.
[1, 1, 2, 2, 3, 3, 4, 5].difference([1, 2, 4]) #=> [3, 3, 5]
dig(index, *identifiers) → object
중첩된 객체에서 인덱스에 해당하는 값을 재귀적으로 찾아요.
a = [[1, [2, 3]]]
a.dig(0, 1, 1) #=> 3
drop(n) → new_array / drop_while {|element| ... } → new_array / drop_while → new_enumerator
drop(n)은 앞의 n개를 버린 새 배열을 돌려줘요. drop_while은 블록이 true인 동안 앞에서 버리고, 처음 false가 나온 뒤부터 남겨요. 블록 없이는 열거자예요.
each {|element| ... } → self / each → Enumerator
각 요소를 순서대로 블록에 넘기고 self를 돌려줘요. 블록 없이는 Enumerator를 돌려줘요.
each_index {|index| ... } → self / each_index → Enumerator
각 인덱스를 블록에 넘겨요.
empty? → true or false
배열이 비어 있는지 확인해요.
eql? other_array → true or false
요소가 동일한지(hash까지 고려한 엄격한 동등 비교) 확인해요.
fetch(index) → element / fetch(index, default_value) → element / fetch(index) {|index| ... } → element
index의 요소를 돌려줘요. 범위 밖이면 기본적으로 IndexError를, 기본값을 주면 그 값을, 블록을 주면 블록 결과를 돌려줘요.
arr = ['a', 'b', 'c']
arr.fetch(100) #=> IndexError
arr.fetch(100, "oops") #=> "oops"
arr.fetch(100) {|i| "#{i}번째는 없어요"} #=> "100번째는 없어요"
fill(obj) → self / fill(obj, start) / fill(obj, start, length) / fill(obj, range) / fill {|index| ... } → self ...
지정한 범위를 값이나 블록 반환값으로 채워요. 인자가 다르면 start, length, range로 영역을 지정할 수 있어요.
a = [0, 1, 2, 3]
a.fill(9) #=> [9, 9, 9, 9]
a.fill(9, 1) #=> [0, 9, 9, 9]
a.fill(9, 1, 2)#=> [0, 9, 9, 3]
a.fill {|i| i*2 } #=> [0, 2, 4, 6]
filter / filter!
select와 select!의 별칭이에요.
find_index / find_index(object) / find_index {|element| ... }
index의 별칭이에요. object와 같은 첫 요소의 인덱스나, 블록이 true인 첫 요소의 인덱스를 돌려줘요.
first → object or nil / first(n) → new_array
첫 요소를 돌려주거나, 앞의 n개 요소 배열을 돌려줘요.
flatten → new_array / flatten(level) → new_array / flatten! → self or nil / flatten!(level) → self or nil
중첩 배열을 평탄화한 새 배열을 돌려줘요. level로 깊이를 제한할 수 있어요(기본은 무한). flatten!은 파괴적이고, 바뀐 게 없으면 nil이에요.
a = [1, [2, [3, [4]]]]
a.flatten #=> [1, 2, 3, 4]
a.flatten(2) #=> [1, 2, 3, [4]]
hash → integer
배열 내용에 기반한 해시 코드를 돌려줘요. eql?로 같은 배열은 같은 해시를 가져요.
include?(obj) → true or false
obj가 배열에 있는지 확인해요.
index(object) → integer or nil / index {|element| ... } → integer or nil / index → new_enumerator
object와 같거나 블록이 true인 첫 요소의 인덱스를 돌려줘요. 없으면 nil. 블록 없이는 열거자예요.
initialize_copy
replace의 별칭이에요. 내부적으로 dup/clone이 자기 요소들을 복사할 때 써요.
insert(index, *objects) → self
index 위치에 objects를 삽입해요. 음수 인덱스는 끝부터 센 위치예요.
a = %w[a b c d]
a.insert(2, 99) #=> ["a", "b", 99, "c", "d"]
a.insert(-2, 1, 2, 3) #=> ["a", "b", 99, "c", 1, 2, 3, "d"]
inspect → new_string
배열을 안전하게 문자열로 표현해요. 요소의 inspect 결과를 [ ]로 감싸요. to_s와 동일한 결과예요.
[1, "two", :three].inspect #=> "[1, \"two\", :three]"
intersect?(other_ary) → true or false
공통 요소가 하나라도 있으면 true를 돌려줘요.
[1, 2, 3].intersect?([3, 4, 5]) #=> true
[1, 2, 3].intersect?([4, 5, 6]) #=> false
intersection(*other_arrays) → new_array
모든 배열에 공통으로 나타나는 요소만 담은 새 배열을 돌려줘요. 결과의 순서는 원본 배열 기준이고, 중복이 제거돼요. 하나의 인자만 주면 중복 제거만 하고 uniq처럼 봐도 돼요.
[1, 1, 3, 5].intersection([1, 2, 3]) #=> [1, 3]
join →new_string / join(separator = $,) → new_string
요소들을 하나의 문자열로 이어 붙여요. 요소가 배열이면 재귀적으로 처리돼요. nil 요소는 빈 문자열로 취급돼요.
["a", "b", "c"].join #=> "abc"
["a", "b", "c"].join("-") #=> "a-b-c"
keep_if {|element| ... } → self / keep_if → new_enumeration
블록이 true인 요소만 남기고 self를 돌려줘요. 블록 없이는 열거자예요.
a = %w[a b c d]
a.keep_if {|x| x >= "c" } #=> ["c", "d"]
last → object or nil / last(n) → new_array
마지막 요소를 돌려주거나, 끝의 n개 요소 배열을 돌려줘요.
length → an_integer / size
요소의 개수를 돌려줘요. size는 length의 별칭이에요.
map {|element| ... } → new_array / map → new_enumerator / map! {|element| ... } → self / map! → new_enumerator
각 요소를 블록 결과로 변환한 새 배열을 돌려줘요(map). map!은 파괴적으로 바꿔요. 블록 없이는 열거자예요. collect/collect!는 별칭이에요.
[1, 2, 3].map {|x| x * 2 } #=> [2, 4, 6]
max → element / max {|a, b| ... } → element / max(n) → new_array / max(n) {|a, b| ... } → new_array
최대 요소를 돌려줘요. 블록으로 비교 규칙을 줄 수 있고, n을 주면 최댓값부터 n개를 배열로 돌려줘요. 빈 배열이면 nil, n이 주어지면 빈 배열이에요.
min → element / min { |a, b| ... } → element / min(n) → new_array / min(n) { |a, b| ... } → new_array
max와 반대로 최소 요소(또는 n개)를 돌려줘요.
minmax → [min_val, max_val] / minmax {|a, b| ... } → [min_val, max_val]
최소·최대를 한 번에 [min, max] 배열로 돌려줘요.
none? → true or false / none? {|element| ... } / none?(obj)
조건을 만족하는 요소가 하나도 없는지 확인해요. 빈 배열이면 true예요.
one? → true or false / one? {|element| ... } / one?(obj)
조건을 만족하는 요소가 정확히 하나인지 확인해요.
pack(template, buffer: nil) → string
요소들을 template 지시자에 따라 패킹해 이진 문자열로 만들어요. Array#pack과 String#unpack은 서로 반대 연산이에요. buffer를 주면 그 문자열을 버퍼로 재사용해요.
["a", "b", "c"].pack("A3A3A3") #=> "a b c "
[1, 2, 3].pack("ccc") #=> "\x01\x02\x03"
permutation {|element| ... } → self / permutation(n) {|element| ... } → self / permutation → new_enumerator ...
모든 순열을 생성해 블록에 넘겨요. permutation(n)은 인덱스 순서 그대로 n개를 고르는 순열이에요. 블록 없이는 열거자예요.
a = [1, 2, 3]
a.permutation(2).to_a #=> [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]
pop → object or nil / pop(n) → new_array
마지막 요소(들)를 꺼내면서 제거하고 돌려줘요. 빈 배열이면 nil(또는 n이 주어지면 빈 배열)이에요.
a = [1, 2, 3, 4]
a.pop #=> 4
a #=> [1, 2, 3]
a.pop(2) #=> [2, 3]
product(*other_arrays) → new_array / product(*other_arrays) {|combination| ... } → self
self와 other_arrays의 모든 조합(데카르트 곱)을 만든 새 배열을 돌려줘요. 인자가 없으면 자기 요소만으로 1-조합을, 블록을 주면 각 조합을 넘기고 self를 돌려줘요.
[1, 2].product([3, 4]) #=> [[1,3],[1,4],[2,3],[2,4]]
push(*objects) → self / append
objects를 끝에 추가하고 self를 돌려줘요. append는 별칭이에요.
a = [1, 2]; a.push(3, 4); a #=> [1, 2, 3, 4]
rassoc(obj) → found_array or nil
각 요소가 배열일 때, 두 번째 요소가 obj == element[1]인 첫 배열을 찾아 돌려줘요.
s1 = ["colors", "red", "blue", "green"]
[ s1 ].rassoc("red") #=> ["colors", "red", "blue", "green"]
[ s1 ].rassoc("green") #=> nil
reject {|element| ... } → new_array / reject → new_enumerator / reject! {|element| ... } → self or nil
블록이 true인 요소를 제외한 새 배열을 돌려줘요(reject). reject!는 파괴적이고, 제거된 게 없으면 nil을 돌려줘요.
[1, 2, 3, 4].reject {|x| x.even? } #=> [1, 3]
repeated_combination(n) {|combination| ... } → self / repeated_combination(n) → new_enumerator
중복을 허용한 조합을 생성해요.
repeated_permutation(n) {|permutation| ... } → self / repeated_permutation(n) → new_enumerator
중복을 허용한 순열을 생성해요.
replace(other_array) → self
self의 모든 요소를 other_array의 요소로 교체해요.
a = [1, 2]; a.replace([3, 4]); a #=> [3, 4]
reverse → new_array / reverse! → self
순서를 뒤집은 새 배열을 돌려주거나(reverse), 파괴적으로 뒤집어요(reverse!).
reverse_each {|element| ... } → self / reverse_each → Enumerator
요소를 역순으로 블록에 넘겨요.
rindex(object) → integer or nil / rindex {|element| ... } → integer or nil / rindex → new_enumerator
index와 반대로 뒤에서부터 찾아 첫 매칭의 인덱스를 돌려줘요.
rotate → new_array / rotate(count) → new_array / rotate! → self / rotate!(count) → self
요소를 count만큼 회전시킨 새 배열을 돌려줘요. count 기본값은 1이고, 음수면 반대 방향이에요.
a = [1, 2, 3, 4]
a.rotate #=> [2, 3, 4, 1]
a.rotate(2) #=> [3, 4, 1, 2]
sample(random: Random) → object / sample(n, random: Random) → new_ary
임의의 요소(들)를 무작위로 돌려줘요. random으로 난수 생성기를 지정할 수 있어요. n을 주면 중복 없는 n개의 임의 요소를 돌려줘요.
select {|element| ... } → new_array / select → new_enumerator / select! {|element| ... } → self or nil
블록이 true인 요소만 담은 새 배열을 돌려줘요(select). select!는 파괴적이고, 바뀐 게 없으면 nil이에요. filter/filter!는 별칭이에요.
[1, 2, 3, 4].select {|x| x.even? } #=> [2, 4]
shelljoin → string
Shellwords.join(self)로, 배열을 셸 명령줄로 쓰기 좋은 문자열로 만들어요. require 'shellwords'가 필요해요.
shift → object or nil / shift(n) → new_array
첫 요소(들)를 꺼내면서 제거하고 돌려줘요. 빈 배열이면 nil(또는 n이 주어지면 빈 배열)이에요.
a = [1, 2, 3]; a.shift #=> 1; a #=> [2, 3]
shuffle(random: Random) → new_ary / shuffle!(random: Random) → array
요소를 무작위로 섞은 새 배열을 돌려주거나(shuffle), 파괴적으로 섞어요(shuffle!).
slice(index) → object or nil / slice(start, length) → object or nil / slice(range) → object or nil / slice(aseq) → object or nil
Array#[]의 별칭이에요.
slice!(n) → object or nil / slice!(start, length) → new_array or nil / slice!(range) → new_array or nil
범위에 해당하는 요소를 배열에서 제거하고 돌려줘요. 제거할 것이 없으면 nil이에요.
a = [1, 2, 3, 4, 5]
a.slice!(1, 2) #=> [2, 3]
a #=> [1, 4, 5]
sort → new_array / sort {|a, b| ... } → new_array / sort! → self / sort! {|a, b| ... } → self
정렬한 새 배열을 돌려주거나(sort), 파괴적으로 정렬해요(sort!). 블록으로 비교 규칙을 줄 수 있어요.
sort_by! {|element| ... } → self / sort_by! → new_enumerator
각 요소를 블록 결과로 변환한 값을 기준으로 정렬해요(파괴적). 블록 없이는 열거자예요.
sum(init = 0) → object / sum(init = 0) {|element| ... } → object
요소들의 합을 돌려줘요. 블록을 주면 각 요소를 변환한 값의 합이에요. init이 시작 값이에요.
[1, 2, 3].sum #=> 6
[1, 2, 3].sum {|x| x * 2 } #=> 12
[].sum(100) #=> 100
take(n) → new_array / take_while {|element| ... } → new_array / take_while → new_enumerator
take(n)은 앞의 n개를 돌려주고, take_while은 블록이 true인 동안 앞에서부터 요소를 모아요.
to_a → self or new_array / to_ary → self
배열을 그대로(또는 사본으로) 돌려줘요. to_ary는 항상 self를 돌려줘요.
to_h → new_hash / to_h {|item| ... } → new_hash
요소가 [key, value] 쌍인 배열을 해시로 변환해요. 블록을 주면 각 요소를 블록으로 변환한 쌍을 사용해요.
[[:foo, :bar], [1, 2]].to_h #=> {:foo=>:bar, 1=>2}
to_s
inspect의 별칭이에요.
transpose → new_array
행과 열을 바꾼 새 배열을 돌려줘요. 모든 요소가 같은 크기의 배열이어야 해요. 그렇지 않으면 IndexError가 나요.
a = [[1,2], [3,4], [5,6]]
a.transpose #=> [[1,3,5], [2,4,6]]
union(*other_arrays) → new_array
self와 other_arrays의 합집합을 돌려줘요. 순서는 처음 나타난 순서 유지, 중복은 제거돼요.
[1, 1, 2, 3].union([3, 4, 5]) #=> [1, 2, 3, 4, 5]
uniq → new_array / uniq {|element| ... } → new_array / uniq! → self or nil / uniq! {|element| ... } → self or nil
중복을 제거한 새 배열을 돌려줘요(uniq). 블록을 주면 그 반환값 기준으로 중복을 판단해요. uniq!는 파괴적이고, 바뀐 게 없으면 nil이에요.
a = [1, 1, 2, 3, 3]; a.uniq #=> [1, 2, 3]
unshift(*objects) → self / prepend
objects를 배열 앞에 추가하고 self를 돌려줘요. prepend는 별칭이에요.
values_at(*indexes) → new_array
지정한 인덱스들의 요소로 새 배열을 만들어요. 중복·범위 밖 인덱스도 허용해요(nil로 채워짐).
a = %w[a b c d e]
a.values_at(0, 2, 4) #=> ["a", "c", "e"]
a.values_at(3, 3, 5, 7) #=> ["d", "d", nil, nil]
zip(*other_arrays) → new_array / zip(*other_arrays) {|other_array| ... } → nil
self의 각 요소를 other_arrays의 대응 요소와 묶어 새 배열을 만들어요. 짧은 쪽에 맞춰 조립하고, 길이가 다르면 누락을 nil로 채워요. 블록을 주면 각 묶음을 넘기고 nil을 돌려줘요.
[1, 2, 3].zip([4, 5, 6], [7, 8, 9])
#=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
array | other_array → new_array
두 배열의 합집합을 돌려줘요. 순서는 첫 번째 배열부터, 중복은 제거돼요.
[1, 1, 2, 3] | [3, 4, 5] #=> [1, 2, 3, 4, 5]
더 알아보기
- Ruby의 다른 컬렉션 타입인
Hash,Range,Set문서도 함께 보면 좋아요. - 배열 리터럴
%w[],%i[]과 문자열 내 배열 변환String#unpack/Array#pack쌍을 참고하세요.