Я новачок у програмуванні. Чи може хтось пояснити, що .map
робити в:
params = (0...param_count).map
Я новачок у програмуванні. Чи може хтось пояснити, що .map
робити в:
params = (0...param_count).map
Відповіді:
map
Метод приймає перелічувальний об'єкт і блок, і запускає блок для кожного елемента, кожен висновок, що повертається з блоку (вихідний об'єкт не змінюється , якщо не використовується map!)
:
[1, 2, 3].map { |n| n * n } #=> [1, 4, 9]
Array
і Range
є численними типами. map
з блоком повертає масив. map!
мутує вихідний масив.
Де це корисно, і в чому різниця між map!
і each
? Ось приклад:
names = ['danil', 'edmund']
# here we map one array to another, convert each element by some rule
names.map! {|name| name.capitalize } # now names contains ['Danil', 'Edmund']
names.each { |name| puts name + ' is a programmer' } # here we just do something with each element
Вихід:
Danil is a programmer
Edmund is a programmer
map
так, ніби воно булоmap!
map
Поряд з select
і each
це одна з конячок Рубі в моєму коді.
Це дозволяє запустити операцію над кожним із об’єктів вашого масиву і повернути їх у все те саме місце. Прикладом може бути збільшення масиву чисел на одне:
[1,2,3].map {|x| x + 1 }
#=> [2,3,4]
Якщо ви можете запустити один метод на елементах свого масиву, ви можете це зробити у стислому стилі так:
Для цього за допомогою наведеного вище прикладу вам доведеться зробити щось подібне
class Numeric
def plusone
self + 1
end
end
[1,2,3].map(&:plusone)
#=> [2,3,4]
Щоб більш просто використовувати техніку швидкого доступу ampersand, давайте скористаємося іншим прикладом:
["vanessa", "david", "thomas"].map(&:upcase)
#=> ["VANESSA", "DAVID", "THOMAS"]
Трансформація даних у Ruby часто включає каскад map
операцій. Вивчення map
& select
, вони - одні з найкорисніших методів Ruby в первинній бібліотеці. Вони так само важливі, як іeach
.
( map
також псевдонім для collect
. Використовуйте те, що найкраще підходить для вас концептуально.)
Більш корисна інформація:
Якщо об'єкт Enumerable, на якому ви працюєте each
або map
на якому, містить набір перелічених елементів (хеші, масиви), ви можете оголосити кожен із цих елементів у ваших блокових трубах так:
[["audi", "black", 2008], ["bmw", "red", 2014]].each do |make, color, year|
puts "make: #{make}, color: #{color}, year: #{year}"
end
# Output:
# make: audi, color: black, year: 2008
# make: bmw, color: red, year: 2014
У випадку Hash (також Enumerable
об'єкт, Hash - це просто масив кортежів зі спеціальними інструкціями для перекладача). Перший "параметр труби" - це ключ, другий - значення.
{:make => "audi", :color => "black", :year => 2008}.each do |k,v|
puts "#{k} is #{v}"
end
#make is audi
#color is black
#year is 2008
Щоб відповісти на власне питання:
Якщо припустити, що params
це хеш, це був би найкращий спосіб відображення через нього: Використовуйте два параметри блоку замість одного, щоб захопити пару ключів і значень для кожного інтерпретованого кортежу в хеші.
params = {"one" => 1, "two" => 2, "three" => 3}
params.each do |k,v|
puts "#{k}=#{v}"
end
# one=1
# two=2
# three=3
NoMethodError: private method 'plusone' called for 1:Fixnum
в ruby 2 та "неправильну кількість args" у ruby 1.9 / 1.8. У всякому разі, я використовував лямбда: plusone = ->(x) { x + 1 }
потім вийняти символ специфікатор: [1,2,3].map(&plusone)
.
private
всередині класу, куди ти поклав свій метод, перш ніж ставити свій метод
0..param_count
означає "до і включаючи param_count".
0...param_count
означає "до, але не включаючи param_count".
Range#map
не повертає Enumerable
, він фактично відображає його в масив. Це те саме, що Range#to_a
.
Він "відображає" функцію до кожного елемента в Enumerable
- у цьому випадку діапазоні. Таким чином, він буде викликати блок, що передається один раз, для кожного цілого числа від 0 до param_count
(виключно - ви маєте рацію щодо крапок) і повертає масив, що містить кожне повернене значення.
Ось документація на Enumerable#map
. Він також має псевдонім, collect
.
Range#map
насправді перетворює його на масив.
Enumerable
, як кожна. Я думав, що це так.
Карта є частиною переліченого модуля. Дуже схоже на "збирати" Наприклад:
Class Car
attr_accessor :name, :model, :year
Def initialize (make, model, year)
@make, @model, @year = make, model, year
end
end
list = []
list << Car.new("Honda", "Accord", 2016)
list << Car.new("Toyota", "Camry", 2015)
list << Car.new("Nissan", "Altima", 2014)
p list.map {|p| p.model}
Map забезпечує значення ітерації через масив, який повертається за допомогою параметрів блоку.
#each
#each
виконує функцію для кожного елемента в масиві. Наступні два уривки коду еквівалентні:
x = 10
["zero", "one", "two"].each{|element|
x++
puts element
}
x = 10
array = ["zero", "one", "two"]
for i in 0..2
x++
puts array[i]
end
#map
#map
застосовує функцію до кожного елемента масиву, повертаючи отриманий масив. Наступні:
array = ["zero", "one", "two"]
newArray = array.map{|element| element.capitalize()}
array = ["zero", "one", "two"]
newArray = []
array.each{|element|
newArray << element.capitalize()
}
#map!
#map!
це як #map
, але змінює масив на місці. Наступні:
array = ["zero", "one", "two"]
array.map!{|element| element.capitalize()}
array = ["zero", "one", "two"]
array = array.map{|element| element.capitalize()}
map
є загальним "функціональним" методом, знайденим на безлічі об'єктів, що використовуються для перетворення значень у послідовності (з особливими міркуваннями)...
і...
є способами створення діапазонів. Крім того, ознайомтеся з REPL, де ви можете спробувати цей матеріал самостійно! :)