问题
The details here aren't important, it's just an example, all that matters is the i=0, i+=1 action
def sortAndIndex
#sorting keys
@disco = Hash[@disco.sort]
#basic setup for both input types
@years = @disco.keys
@albums = @disco.values
sum = @years.count
#setup for "albums" input
@allalbums = []
i = 0
sum.times do
thatyear = @years[i] + ", " + @albums[i]
@allalbums << thatyear
i += 1
end
end
Now this does work, as should any other "i++" type ("C-style") iterator in ruby or most other languages. However, I keep hearing that ruby has this better way to do this, where basically I'd be passing a second parameter variable other than, here, 'a'.
What modifications would I make to do this and are there multiple "shortcuts" which ruby has involving these sorts of i++ ary[i] iterator problems?
回答1:
Yes, you should do things the "Ruby way" and forget about indexing. Why? Because it is idiomatic and looks nicer. You pass in a block of code to be executed upon each element of a collection. How the elements are stored, in what order, if they can be indexed into, is all irrelevant.
# nice, eh?
some_array.each do |elem|
some_action(elem)
end
If you need an index counter (you don't in your example) use each_with_index
instead.
Also note that the concept of blocks is important in Ruby outside of iterating a collection. What you have there is... odd... and you should listen to them, but many methods take blocks as arguments (or optional arguments) which do not return collections which can be indexed. For example, File.open
takes a block and, if supplied, closes the file for you when the block returns
Also, another thing to note; your naming conventions are atypical for Ruby. Rubyists use lowercase function and variable names with underscores_between_words
. Best to stick with the community here.
回答2:
People are telling you about this:
ary.each do |a|
puts a
end
Much simpler, isn't it?
Update
This is how I would write your updated example in idiomatic ruby
def sort_and_index
@disco.sort.map do |year, album|
"#{year}, #{album}"
end
end
I'm not sure, if you needed all those instance variables for later use or not.
回答3:
The times
method doesn't pass a second argument to the block. You may be looking for each_with_index
, which passes the object and the index of that object to the block:
ary.each_with_index do |object, i|
puts "Index #{i} => #{object.inspect}"
end
But ultimately yes, Ruby has several ways to iterate over a collection, and they're all better than C-style for
loops :-)
来源:https://stackoverflow.com/questions/11403712/people-keep-telling-me-im-writing-c-style-iterators-in-ruby-and-that-im-sup