Dönüştürmenin en kolay yolu nedir
[x1, x2, x3, ... , xN]
için
[[x1, 2], [x2, 3], [x3, 4], ... , [xN, N+1]]
Dönüştürmenin en kolay yolu nedir
[x1, x2, x3, ... , xN]
için
[[x1, 2], [x2, 3], [x3, 4], ... , [xN, N+1]]
Yanıtlar:
Ruby 1.8.7 veya 1.9 kullanıyorsanız, yineleyici yöntemlerinin each_with_index
, blok olmadan çağrıldığında, gibi yöntemleri Enumerator
çağırabileceğiniz bir nesneyi döndürme Enumerable
gibi kullanabilirsiniz map
. Böylece şunları yapabilirsiniz:
arr.each_with_index.map { |x,i| [x, i+2] }
1.8.6'da şunları yapabilirsiniz:
require 'enumerator'
arr.enum_for(:each_with_index).map { |x,i| [x, i+2] }
map
bir yöntemdir Enumerable
. each_with_index
Bir bloğun olmadan çağrıldığında, bir döner Enumerator
hangi karışımlar, (1.8.7+ olarak) nesneyi Enumerable
aramak, böylece map
, select
, reject
sadece bir dizi, karma olduğu gibi, üzerinde vs., vs. aralığı
arr.map.with_index{ |o,i| [o,i+2] }
map.with_index
1.8.7'de çalışmaz ( map
1.8'de blok olmadan çağrıldığında bir dizi döndürür).
Ruby'de Enumerator # with_index (offset = 0) vardır , bu nedenle önce Object # to_enum veya Array # map kullanarak diziyi bir numaralandırıcıya dönüştürün :
[:a, :b, :c].map.with_index(2).to_a
#=> [[:a, 2], [:b, 3], [:c, 4]]
foo = ['d'] * 5; foo.map!.with_index { |x,i| x * i }; foo #=> ["", "d", "dd", "ddd", "dddd"]
Üst şaşkınlık üzerinde:
arr = ('a'..'g').to_a
indexes = arr.each_index.map(&2.method(:+))
arr.zip(indexes)
Numaralandırıcı kullanmadan 1.8.6 (veya 1.9) için iki seçenek daha:
# Fun with functional
arr = ('a'..'g').to_a
arr.zip( (2..(arr.length+2)).to_a )
#=> [["a", 2], ["b", 3], ["c", 4], ["d", 5], ["e", 6], ["f", 7], ["g", 8]]
# The simplest
n = 1
arr.map{ |c| [c, n+=1 ] }
#=> [["a", 2], ["b", 3], ["c", 4], ["d", 5], ["e", 6], ["f", 7], ["g", 8]]
Bu tarzın sözdiziminden her zaman keyif aldım:
a = [1, 2, 3, 4]
a.each_with_index.map { |el, index| el + index }
# => [1, 3, 5, 7]
Çağırmak each_with_index
, endeksinizle kolayca eşleştirebileceğiniz bir numaralandırıcı sağlar.
Bunu yapmanın eğlenceli ama faydasız bir yolu:
az = ('a'..'z').to_a
azz = az.map{|e| [e, az.index(e)+2]}
A fun, but useless way
. +2
OP'nin istediği çıktıyı yaratmak
a = [1, 2, 3]
p [a, (2...a.size+2).to_a].transpose
module Enumerable
def map_with_index(&block)
i = 0
self.map { |val|
val = block.call(val, i)
i += 1
val
}
end
end
["foo", "bar"].map_with_index {|item, index| [item, index] } => [["foo", 0], ["bar", 1]]
map.with_index
zaten yakutta var. Numaralandırılabilir sınıfı yeniden açmayı ve zaten var olan bir şeyi eklemeyi neden önerirsiniz?
each_with_index.map
vb. Gibi garip şeyler kullanmak zorunda kalmak yerine 1.8.6 ve 1.8.7 (evet bazılarımız hala kullanıyor) için daha kolay bir yol olabilir ve daha yeni sürümlerde olanlarımız bile kullanmayı tercih edebilir map.with_index FWIW :)
Bunu sık sık yaparım:
arr = ["a", "b", "c"]
(0...arr.length).map do |int|
[arr[int], int + 2]
end
#=> [["a", 2], ["b", 3], ["c", 4]]
Dizinin öğeleri üzerinde doğrudan yineleme yapmak yerine, bir dizi tamsayı üzerinde yineleme yapıyor ve bunları dizinin öğelerini almak için dizinler olarak kullanıyorsunuz.
.each_with_index.map
?