배열(Array)이란 무엇일까요?
배열은 Ruby에 내장된 클래스로, 0개 이상의 요소를 목록 형태로 담는 자료구조입니다. 요소를 쉽게 추가하고, 접근하고, 반복 처리할 수 있도록 다양한 메소드를 함께 제공합니다.
배열이 없다면 값 하나하나마다 별도의 변수를 만들어야 하기 때문에 매우 불편할 것입니다.
예를 들어:
a = 1 b = 2 c = 3
하지만 배열을 사용하면 이렇게 간단해집니다:
numbers = [1, 2, 3]
배열의 가장 큰 장점은 무엇일까요?
어떤 객체든 배열 안에 넣을 수 있다는 것입니다!
- 숫자(Numbers)
- 문자열(Strings)
- 심지어 다른 배열까지! (이 경우 다차원 배열이 됩니다)
지금부터 배열을 제대로 활용할 수 있도록 하나씩 살펴보겠습니다.
1. 배열은 0부터 인덱싱됩니다
배열 안의 요소에 접근하려면 인덱스(index)를 사용하며, 이 인덱스는 0부터 시작합니다.
예를 들어 "cat", "dog", "tiger"라는 단어가 들어 있는 배열은 아래와 같이 표현됩니다:
["cat", "dog", "tiger"]
인덱스 0에는 "cat", 1에는 "dog", 2에는 "tiger"가 저장되어 있습니다. 이제 배열로 할 수 있는 다양한 작업들을 알아보겠습니다!
2. Ruby 배열 메소드
먼저 배열을 생성하는 방법부터 알아보겠습니다.
빈 배열을 만든 후 요소를 추가하는 방법과, 처음부터 값을 넣어서 생성하는 방법 두 가지가 있습니다.
빈 배열 초기화:
users = []
값을 포함한 배열 초기화:
users = ["john", "david", "peter"]
문자열만 담는 배열을 만들 때는 %w를 사용하면 매번 따옴표를 입력하는 번거로움을 줄일 수 있습니다.
예제:
users = %w(john david peter)
이제 배열이 준비되었으니, 그 안의 요소에 접근하는 방법을 살펴보겠습니다.
접근 방법:
users[0] # 배열의 첫 번째 요소 users[1] # 배열의 두 번째 요소 users[2] # 배열의 세 번째 요소
first와 last 메소드를 사용할 수도 있습니다:
users.first # 배열의 첫 번째 요소 users.last # 배열의 마지막 요소
배열에 요소를 추가하는 방법:
# 두 방법 모두 같은 결과를 냅니다. 보통 << 을 더 선호합니다. users.push "andrew" users << "andrew"
배열에서 요소를 삭제하는 방법:
last_user = users.pop # 배열의 마지막 요소를 제거하고 반환합니다 user.delete_at(0) # 배열의 첫 번째 요소를 제거합니다
또한 shift와 unshift 메소드도 있습니다. pop/push와 비슷하지만 배열의 앞쪽에서 요소를 가져오거나 추가합니다.
users.unshift "robert" # 배열 맨 앞에 요소를 추가합니다 users.shift # 배열의 첫 번째 요소를 제거하고 반환합니다
특정 값이 배열에 포함되어 있는지 확인하기:
numbers = [1,2,3] numbers.include?(2) # true numbers.include?(10) # false
배열의 길이(요소 개수) 구하기:
words = ["cat", "coconut", "bacon"] words.size # 3
핵심 메소드 치트시트:
| 작업 | 메소드 |
|---|---|
| 생성(initialize) | Array.new, [], %w |
| 읽기(read) | [0], first, last |
| 추가(add) | push, <<, unshift |
| 삭제(remove) | pop, delete_at, shift |
3. 배열을 문자열로 변환하는 방법
Array#join 메소드를 사용하면 어떤 배열이든 문자열로 변환할 수 있습니다.
예제:
letters = %w(a b c d) letters.join # "abcd"
join 메소드는 선택적 파라미터 1개를 받을 수 있으며, 이를 통해 요소들이 연결될 때 사이에 들어갈 구분자를 지정할 수 있습니다.
letters = %w(a b c d)
letters.join(" ")
# "a b c d"
반대로 문자열을 배열로 변환하고 싶다면 split 메소드를 사용하세요:
"a b c".split
결과는 다음과 같습니다:
["a", "b", "c"]
4. 다차원 배열 (2차원 배열 & 그 이상)
배열 안에 또 다른 배열을 넣을 수 있는데, 이를 다차원 배열(multi-dimensional array)이라고 부릅니다.
2차원 배열 예제:
users = [ [1, 'Peter'], [2, 'Steven'] ]
첫 번째 하위 배열의 첫 번째 요소에 접근하려면 다음 문법을 사용합니다:
users[0][0] # 1
첫 번째 하위 배열의 두 번째 요소에 접근하려면:
users[0][1] # 'Peter'
다차원 배열을 일반 배열로 변환하고 싶은 경우가 종종 있습니다. 이럴 때는 flatten 메소드를 사용하세요:
users.flatten # [1, "Peter", 2, "Steven"]
5. Ruby 배열 순회(반복 처리) 방법
배열의 내용을 하나씩 꺼내서 출력하거나 처리하고 싶다면 어떻게 해야 할까요?
다행히 Ruby는 강력한 반복 메소드들을 제공합니다!
예제: each 메소드로 배열 출력하기
users.each { |item| puts item }
값과 인덱스를 모두 사용해야 한다면 each_with_index 메소드를 활용하세요:
users.each_with_index { |item, idx| puts "#{item} with index #{idx}" }
참고: 위 대부분의 반복 작업은 Enumerable 모듈 덕분에 가능합니다. 이 모듈은 기본적으로 Array 클래스에 믹스인(mixin)되어 있습니다.
예제: map으로 배열의 모든 단어를 대문자화하기
users = users.map { |user| user.capitalize }
users = users.map(&:capitalize)
map 메소드는 원본 배열을 직접 수정하지 않고 수정된 요소들로 이루어진 새 배열을 반환합니다. 따라서 결과를 변수에 다시 할당해야 합니다.
배열을 직접 변경하는 map!(느낌표가 붙은) 메소드도 있지만, 일반적으로는 더 간단한 버전을 사용하는 것이 권장됩니다.
또한 특정 조건에 맞는 요소만 골라내고 싶을 때가 있습니다.
예제: 10보다 큰 숫자 찾기
numbers = [3, 7, 12, 2, 49]
numbers.select { |n| n > 10 }
# => 12, 49
6. 음수 인덱싱
Ruby 배열에서 특정 요소에 접근하려면 인덱싱(또는 first, last 같은 메소드)을 사용한다고 배웠습니다.
그런데 음수 인덱싱은 어떨까요?
말하자면 -1처럼 음수를 배열 인덱스로 사용하는 것입니다.
Ruby는 배열의 끝에서부터 거꾸로 접근합니다. 즉 -1은 마지막 요소, -2는 뒤에서 두 번째 요소를 의미합니다.
예제:
letters = ["a", "b", "c"] letters[-1] # "c" letters[-2] # "b"
7. 더 많은 배열 연산
배열로 할 수 있는 작업은 정말 다양합니다. 정렬, 무작위 요소 추출 등이 대표적입니다.
sort 메소드로 배열을 정렬할 수 있습니다. 배열에 문자열이나 숫자만 있다면 잘 동작하며, 더 복잡한 정렬이 필요하면 sort_by를 확인해 보세요.
numbers = numbers.sort
배열에서 중복 요소를 제거할 수도 있습니다. 이런 작업을 자주 한다면 Set 사용을 고려해 보는 것도 좋습니다.
numbers = [1, 3, 3, 5, 5] numbers = numbers.uniq # => [1, 3, 5]
주의할 점은 이 메소드가 원본 배열을 영구적으로 변경하지 않는다는 것입니다. 대부분의 Ruby 메소드는 변경 사항이 적용된 새 배열을 생성합니다. 따라서 결과를 저장하려면 변수에 할당하거나, 이 예제에서는 uniq! 메소드를 사용하면 됩니다.
배열에서 무작위로 하나의 요소를 뽑고 싶다면 sample 메소드를 사용하세요:
numbers.sample
배열 전체가 아니라 일부만 잘라내고(slicing) 싶을 때도 있습니다.
예제: 원본을 변경하지 않고 배열의 처음 3개 요소 가져오기
numbers.take(3) numbers[0,3]
더 고급 슬라이싱도 가능합니다. 예를 들어 첫 번째 요소를 제외한 나머지 전체를 얻고 싶다면:
numbers[1..-1]
콤마(0,3)와 범위(1..-1)의 차이에 주목하세요. 전자는 "인덱스 0부터 3개의 요소를 가져와라"라는 의미이고, 후자는 "이 범위에 해당하는 요소들을 가져와라"라는 의미입니다.
배열의 크기 구하기:
numbers.size # 5
배열이 비어 있는지 확인하기:
numbers.empty? # false
nil 값 제거하기:
numbers << nil # [1, 3, 3, 5, 5, nil] numbers.compact # [1, 3, 3, 5, 5]
8. 여러 배열 간의 연산
두 개의 배열을 하나로 합치고 싶다면 다음과 같이 할 수 있습니다:
# 더 빠름: users 배열 자체를 변경합니다 users.concat(new_users) # 더 느림: 새로운 배열을 생성합니다 users += new_users
한 배열에서 다른 배열의 요소들을 제거할 수도 있습니다. 여기서 users_to_delete 역시 배열입니다:
users = users - users_to_delete
마지막으로, 두 배열에 공통으로 존재하는 요소들을 구할 수 있습니다:
users & new_users
마무리
Ruby 배열은 매우 유용하며, 코딩 과정에서 든든한 조력자가 되어줄 것입니다.
배열 생성, 요소 추가, 인덱스로 요소 접근 등을 직접 연습해 보세요. 또한 Ruby 해시(Hash)에 대해서도 읽어보시길 권합니다. 해시는 배열과 결합하여 더 흥미로운 코드를 작성할 수 있는 또 다른 중요한 클래스입니다.
연습이 완벽을 만듭니다!
이 글이 도움이 되었다면 주변에 공유하고 뉴스레터도 구독해 주세요 🙂