All original content is created in Ukrainian. Not all content has been translated yet. Some posts may only be available in Ukrainian.Learn more

Що означає .map(&:name) в Ruby?

Post cover: Що означає .map(&:name) в Ruby?
Table of contentsClick link to navigate to the desired location
This content has not been translated yet.We're showing the original Ukrainian content below.
У Ruby конструкція map(&:name) є скороченням для застосування методу до кожного елемента колекції. Ця форма використовується для того, щоб код був коротшим і більш читабельним. Розглянемо детальніше, що саме означає цей вираз.
Метод map використовується для проходження по кожному елементу колекції (ітерація) і виконання блоку коду для кожного елемента. У відповідь повертається новий масив з результатами виконання блоку.
[1, 2, 3].map { |n| n * 2 }
# => [2, 4, 6]

Що означає &:name?

Ця (&:name у виразі array.map(&:name)) частина використовується для скорочення блоку, який викликає метод name для кожного елемента. Вона еквівалентна:
array.map { |item| item.name }
Тобто:
# Ось це:
array.map { |item| item.name }
# Та це:
array.map(&:name)
# Виконує одну й ту саму дію, але другий варіант має скорочений вигляд

Приклад

class User
  attr_accessor :name

  def initialize(name)
    @name = name
  end
end

users = [User.new('Alice'), User.new('Bob'), User.new('Charlie')]
names = users.map(&:name)
# => ["Alice", "Bob", "Charlie"]

# Спробуємо 'довший' варіант
names = users.map{ |user| user.name }
# => ["Alice", "Bob", "Charlie"]
Як ми бачимо, обидва варіанти роблять одне й те саме. А що з перформансом? Давайте перевіремо бенчмарки.

Бенчмарки

require 'benchmark'

class User
  attr_accessor :name

  def initialize(name)
    @name = name
  end
end

# Генерація великого масиву користувачів
users = Array.new(100_000) { |i| User.new("User#{i}") }

# Бенчмаркінг
results = Benchmark.bm do |x|
  x.report('map(&:name)') do
    users.map(&:name)
  end

  x.report('map { |user| user.name }') do
    users.map { |user| user.name }
  end
end

puts results
Результат на моїй машині:
[#<Benchmark::Tms:0x000000010dd19ad0 @cstime=0.0, @cutime=0.0, @label="map(&:name)", @real=0.008466999977827072, @stime=0.00038199999999999346, @total=0.0077390000000007175, @utime=0.007357000000000724>,
 #<Benchmark::Tms:0x000000010dd19670 @cstime=0.0, @cutime=0.0, @label="map { |user| user.name }", @real=0.008027000352740288, @stime=0.0003069999999999462, @total=0.007962000000001468, @utime=0.007655000000001522>]
Взагалі, скорочений варіант більш оптимізований та швидкий. Але в моєму прикладі результат приблизно однаковий. Треба мати більш масивний набір даних, щоб бенчмарк показав різницю. Тож за замовчуванням, використовуйте скорочену (оптимізовану версію) виклику методу map. Можливо, зроблю окремий допис з бенчмарками.

This post doesn't have any additions from the author yet.

[Фікс] extconf.rb failed під час встановлення Ruby-бібліотеки Gosu
27 Jun 16:38

[Фікс] extconf.rb failed під час встановлення Ruby-бібліотеки Gosu

meme code
meme code@memecode
How to make an empty git commit?
28 Jun 08:33

How to make an empty git commit?

meme code
meme code@memecode
Ruby-бібліотека Gosu для створення 2D-ігор
29 Jun 08:48

Ruby-бібліотека Gosu для створення 2D-ігор

meme code
meme code@memecode
Gosu Ruby Tutorial - пройдемось по офіційній документації
03 Jul 11:50

Gosu Ruby Tutorial - пройдемось по офіційній документації

meme code
meme code@memecode
Пишемо демо-гру Drones vs Zombies (Gosu / Ruby)
12 Jul 12:17

Пишемо демо-гру Drones vs Zombies (Gosu / Ruby)

meme code
meme code@memecode
How to fix a Windows crash caused by CrowdStrike?
19 Jul 13:53

How to fix a Windows crash caused by CrowdStrike?

meme code
meme code@memecode
Як працює метод map в Ruby? Огляд роботи методу з прикладами
30 Jul 07:33

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

meme code
meme code@memecode
Що означає крапка на початку файлу(.gitignore, .DS_Store, .bashrc тощо)?
02 Aug 13:15

Що означає крапка на початку файлу(.gitignore, .DS_Store, .bashrc тощо)?

meme code
meme code@memecode
Що таке .gitignore? Для чого потрібен та як використовувати
02 Aug 14:58

Що таке .gitignore? Для чого потрібен та як використовувати

meme code
meme code@memecode
Як видалити файл .DS_Store з Git репозиторію?
02 Aug 19:34

Як видалити файл .DS_Store з Git репозиторію?

meme code
meme code@memecode
Що таке ідемпотентний метод?
21 Aug 20:57

Що таке ідемпотентний метод?

meme code
meme code@memecode
What is a repository?
21 Aug 21:25

What is a repository?

meme code
meme code@memecode