Обкладинка нотатки: Як працює метод map в Ruby? Огляд роботи методу з прикладами

Як працює метод map в Ruby? Огляд роботи методу з прикладами

Зміст дописунатисність на посилання, щоб перейти до потрібного місця
Метод map є одним із найуживаніших методів у Ruby, що використовується для обробки колекцій. Він дозволяє застосувати блок коду до кожного елементу колекції і повернути нову колекцію з результатами виконання блоку. Насправді це і все пояснення. Але будь-яка інформація засвоюється краще не на абстракціях, а на простих і реальних прикладах. Тож розглянемо метод map трохи детальніше.

Як працює map

Метод map приймає блок, який виконується для кожного елементу колекції. Результати виконання цього блоку збираються в новий масив, який і повертається методом map.
Виконаємо збільшення кожного елементу масиву на 1 (інкремент)
numbers = [1, 2, 3, 4, 5]
incremented_numbers = numbers.map { |n| n + 1 }

incremented_numbers

Результат
=> [2, 3, 4, 5, 6]
Якщо спрощено:
Ми маємо змінну numbers, яка містить в собі масив елементів (колекція елементів) [1, 2, 3, 4, 5].
Далі ми створюємо змінну incremented_numbers та записуємо в неї результат виконання методу map.
Розглянемо конструкцію map:
numbers.map { |n| n + 1 }

# numbers - наша змінна (колекція)
# .map - виклик методу на змінній
# { |n| n + 1 } - блок, який буде виконано для кожного елементу колекції
Тут треба розглянути сам блок:
{ |n| n + 1 }
  • {} - фігурні дужки: Це тіло блоку, де міститься код, який буде виконано для кожного елементу масиву.
  • |n| - змінна: Це параметр блоку. Кожен елемент масиву передається в цю змінну один за одним.
  • n + 1: Це вираз, що виконується для кожного елементу. Він додає 1 до значення змінної n.
Коли ми виконуємо numbers.map { |n| n + 1 }, ось що відбувається:
Для першого елементу 1:
  • n стає 1
  • Виконується 1 + 1
  • Результат 2 додається до нового масиву
Для другого елементу 2:
  • n стає 2
  • Виконується 2 + 1
  • Результат 3 додається до нового масиву
І так далі для кожного елементу масиву. Новий масив записуємо у змінну incremented_numbers та дивимось її зміст
numbers = [1, 2, 3, 4, 5]
incremented_numbers = numbers.map { |n| n + 1 }
incremented_numbers

Результат
=> [2, 3, 4, 5, 6]
А що станеться зі змінною numbers? Нічого, вона залишається незмінною.
Ще один приклад:
words = ["hello", "world", "ruby"]
new_words = words.map { |word| word.upcase }

new_words
=> ["HELLO", "WORLD", "RUBY"]
words
=> ["hello", "world", "ruby"]
Метод upcase модифікує літери (робить великими). Тож змінна new_words має модифіковані слова, а words залишається незмінною.
Доречі, в цих прикладах ми використовуємо конструкцію блоку у фігурних дужка. Блок також можна передавати через do ... end (у випадках, коли код задовгий і непогано б було його розділити на декілька рядків). Тобто:
numbers.map { |n| n + 1 }

теж саме що й

numbers.map do |n| 
  n + 1
end
Ну й приклад з передачею результату у змінну:
incremented_numbers_braces = numbers.map { |n| n + 1 }

incremented_numbers_do_end = numbers.map do |n| 
  n + 1
end
Ще один приклад, але будемо модифікувати hash
hash = { a: 1, b: 2, c: 3 }
incremented_hash = hash.map { |key, value| [key, value + 1] }

incremented_hash
=> [[:a, 2], [:b, 3], [:c, 4]]
Але є нюанс. Виконання map повертає нам Array (масив). Тож нам треба конвертнути Array у Hash (за допомогою методу .to_h).
incremented_hash = incremented_hash.to_h

incremented_hash
=> {:a=>2, :b=>3, :c=>4}
Я думаю, що в конструкції hash.map { |key, value| [key, value + 1] } доволі зрозуміло, що ми беремо key та value з кожного елементу хешу та повертаємо таку конструкцію [key, value + 1].
Тобто результатом виконня map для елементу буде повернення масиву, де перший елемент - key, а другий - модифіковане value (value + 1).
Результат виконання на всій колекції такий:
incremented_hash
=> [[:a, 2], [:b, 3], [:c, 4]]
Масив масивів. Які вже потім ми конвертуємо у hash (виклик to_h).

map! - модифікує оригінальний масив

Знак оклику доданий до методу map означає, що оригінальна колекція (змінна) буде модифікована. Такий тип виклику методу треба використовувати обережно.
numbers = [1, 2, 3, 4, 5]
numbers.map! { |n| n + 1 }

numbers
=> [2, 3, 4, 5, 6]
  • map: Створює новий масив, залишаючи оригінальний масив незмінним.
  • map!: Модифікує оригінальний масив, змінюючи його елементи на місці.

Чому така назва методу (map)?

Назва map походить від математичної операції "відображення" (mapping), де кожен елемент одного набору "відображається" у відповідний елемент іншого набору. В програмуванні це означає застосування функції або блоку коду до кожного елементу колекції, щоб створити нову колекцію з результатами цих застосувань.
Метод map у Ruby є потужним інструментом для обробки колекцій, що дозволяє легко створювати нові колекції, перетворюючи кожен елемент за допомогою заданого блоку. Він має додаткові можливості (наприклад використання індексів) альтернативи (наприклад each) і навіть синоніми (collect). Але метою цього допису було пояснити принцип роботи методу map без сильних ускладнень. Інші штуки розглянемо в наступних дописах про Ruby. 
🤖 Категорії підібрані ШІ: Програмне забезпеченняТехнології

🔗 Цитувати допис: "Як працює метод map в Ruby? Огляд роботи методу з прикладами"

Якщо ви хочете процитувати цей допис у своїй роботі, статті, блозі, використовуйте наведену нижче інформацію.

Розгорнути деталі


🙌 Підтримати блог @memecode

Ви можете поширити цей допис у соцмережах, чим допоможете платформі цейво розвиватись (* ^ ω ^)

📝 Більше публікацій:
Обкладинка нотатки: Як зробити пустий git commit?
Обкладинка нотатки: Ruby-бібліотека Gosu для створення 2D-ігор
Обкладинка нотатки: Gosu Ruby Tutorial - пройдемось по офіційній документації
Обкладинка нотатки: Пишемо демо-гру Drones vs Zombies (Gosu / Ruby)
Обкладинка нотатки: Як пофіксити збій Windows викликаний CrowdStrike?
Обкладинка нотатки: Що означає .map(&:name) в Ruby?
Обкладинка нотатки: Що означає крапка на початку файлу(.gitignore, .DS_Store, .bashrc тощо)?
Обкладинка нотатки: Що таке .gitignore? Для чого потрібен та як використовувати
Обкладинка нотатки: Як видалити файл .DS_Store з Git репозиторію?
Обкладинка нотатки: Що таке ідемпотентний метод?
Обкладинка нотатки: Що таке репозиторій?
Обкладинка нотатки: Що таке коміт (commit) у контексті програмування та SCM / Git?
Дисклеймер

Інформація на сайті tseivo.com є суб'єктивною та відображає особисті погляди та досвід авторів та авторок блогів.

Використовуйте цей ресурс як одне з декількох джерел інформації під час своїх досліджень та прийняття рішень. Завжди застосовуйте критичне мислення. Людина сама несе відповідальність за свої рішення та дії.