Cách dễ nhất để chuyển đổi là gì
[x1, x2, x3, ... , xN]
đến
[[x1, 2], [x2, 3], [x3, 4], ... , [xN, N+1]]
Cách dễ nhất để chuyển đổi là gì
[x1, x2, x3, ... , xN]
đến
[[x1, 2], [x2, 3], [x3, 4], ... , [xN, N+1]]
Câu trả lời:
Nếu bạn đang sử dụng ruby 1.8.7 hoặc 1.9, bạn có thể sử dụng thực tế là các phương thức lặp như each_with_index
khi được gọi mà không có khối, trả về một Enumerator
đối tượng mà bạn có thể gọi Enumerable
các phương thức như map
trên. Vì vậy, bạn có thể làm:
arr.each_with_index.map { |x,i| [x, i+2] }
Trong 1.8.6 bạn có thể làm:
require 'enumerator'
arr.enum_for(:each_with_index).map { |x,i| [x, i+2] }
map
là một phương pháp Enumerable
như mọi khi. each_with_index
, Khi gọi mà không có khối, trả về một Enumerator
đối tượng (trong 1.8.7+), trong đó hỗn hợp trong Enumerable
, vì vậy bạn có thể gọi map
, select
, reject
vv trên nó giống như trên một mảng, băm, dao động, vv
arr.map.with_index{ |o,i| [o,i+2] }
map.with_index
không hoạt động trong 1.8.7 ( map
trả về một mảng khi được gọi mà không có khối trong 1.8).
Ruby có Enumerator # with_index (offset = 0) , vì vậy trước tiên hãy chuyển đổi mảng thành một liệt kê bằng Object # to_enum hoặc Array # map :
[: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"]
Trên obfuscation hàng đầu:
arr = ('a'..'g').to_a
indexes = arr.each_index.map(&2.method(:+))
arr.zip(indexes)
Dưới đây là hai tùy chọn khác cho 1.8.6 (hoặc 1.9) mà không cần sử dụng liệt kê:
# 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]]
Tôi luôn thích cú pháp của phong cách này:
a = [1, 2, 3, 4]
a.each_with_index.map { |el, index| el + index }
# => [1, 3, 5, 7]
Gọi cho each_with_index
bạn một điều tra viên bạn có thể dễ dàng lập bản đồ với chỉ mục của bạn có sẵn.
Một cách thú vị, nhưng vô dụng để làm điều này:
az = ('a'..'z').to_a
azz = az.map{|e| [e, az.index(e)+2]}
A fun, but useless way
. +2
là để tạo đầu ra mà OP yêu cầu
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
đã tồn tại trong ruby. Tại sao đề nghị mở lại lớp vô số và thêm một cái gì đó đã tồn tại?
each_with_index.map
v.v. và ngay cả những người trong chúng ta trên các phiên bản mới hơn có thể thích sử dụng nó hơn map.with_index FWIW :)
Tôi thường làm điều này:
arr = ["a", "b", "c"]
(0...arr.length).map do |int|
[arr[int], int + 2]
end
#=> [["a", 2], ["b", 3], ["c", 4]]
Thay vì lặp trực tiếp qua các phần tử của mảng, bạn đang lặp qua một loạt các số nguyên và sử dụng chúng làm chỉ số để truy xuất các phần tử của mảng.
.each_with_index.map
?