Array 클래스

Array 클래스

Array는 정수 인덱스로 접근하는 순서 있는 객체 컬렉션이에요. 요소(element)라고 부르는 각 원소에는 어떤 객체든(심지어 다른 배열도) 들어갈 수 있고, 서로 다른 타입의 객체를 한 배열에 담을 수 있어요.

출처: Ruby 4.0 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) #=> 1
  • sliceArray#[]와 똑같이 동작해요.
  • 인덱스가 배열 범위를 벗어날 때 에러를 내고 싶거나, 그때 기본값을 주고 싶으면 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"
  • firstlast는 각각 첫·마지막 요소를 돌려줘요.
  • 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

objectto_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

appendpush의 별칭, prependunshift의 별칭이에요.

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!

mapmap!의 별칭이에요. 각 요소를 블록 결과로 변환한 새 배열을 돌려주거나(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!

selectselect!의 별칭이에요.

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

요소의 개수를 돌려줘요. sizelength의 별칭이에요.

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#packString#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

selfother_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

selfother_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 쌍을 참고하세요.