Руби найти следующий в массиве - PullRequest
9 голосов
/ 04 января 2011

В любом случае можно найти следующий элемент в Ruby Array?

Код:

# Find ALL languages
if !debug
  lang = Language.all
else
  lang = Language.where("id = ? OR id = ?", 22, 32)
end

# Get all elements
elements = Element.where("human_readable IS NOT NULL")

lang.each do |l|
  code = l.code.downcase
  if File.exists?(file_path + code + ".yml")
    File.delete(file_path + code + ".yml")
  end

  t1 = Time.now

  info = {}
  elements.each do |el|
    unless l.id == 1
      et = el.element_translations.where("language_id = ? AND complete = ?", l.id, true)
    else
      et = el.element_translations.where("language_id = ?", 1)
    end
    et.each do |tran|
      info[code] ||= {}
      info[code][el.human_readable] = tran.content.gsub("\n", "").force_encoding("UTF-8").encode!
    end
  end
  File.open(file_path + code + ".yml", "w", :encoding => "UTF-8") do |f|
    if f.write(info.to_yaml)
      t2 = Time.now

      puts code + ".yml File written"
      puts "It took " + time_diff_milli(t1, t2).to_s + " seconds to complete"
      # This is where I want to display the next item in the lang array
      puts lang.shift(1).inspect
      puts "*"*50
    end
  end
end

Ответы [ 5 ]

31 голосов
/ 04 января 2011

Array включает Enumerable, поэтому вы можете использовать each_with_index:

elements.each_with_index {|element, index|
   next_element = elements[index+1]
   do_something unless next_element.nil?
   ...

}
27 голосов
/ 04 января 2011

Хороший способ итерации по Enumerable, если вам нужен доступ как к элементу, так и к следующему, использует each_cons:

arr = [1, 2, 3]
arr.each_cons(2) do |element, next_element|
   p "#{element} is followed by #{next_element}"
   #...
end

# => "1 is followed by 2", "2 is followed by 3".

Как указывает Phrogz, Enumerable#each_cons доступен в Ruby 1.8.7+; для Ruby 1.8.6 вы можете require 'backports/1.8.7/enumerable/each_cons'.

Как указывает @Jacob, другой подход заключается в использовании each_with_index.

4 голосов
/ 04 января 2011
arr[n..-1].find_index(obj) + n
2 голосов
/ 21 марта 2019
foo = ["alpha", "beta", "gamma", "delta"]
foo[foo.find_index("beta") + 1] 
2 голосов
/ 21 ноября 2014

Основываясь на хорошем ответе Марка-Андреса, я хочу дать ответ, который в общих чертах дает следующий элемент для всех элементов, в том числе и последнего, путем дополнения nil:

arr = [1, 2, 3]
[arr, nil].flatten.each_cons(2) do |element, next_element|
   p "#{element} is followed by #{next_element || 'nil'}"
end

# "1 is followed by 2"
# "2 is followed by 3"
# "3 is followed by nil"

Теперь, пока мы на нем, мы также можем предоставить предыдущий элемент для всех элементов:

arr = [1, 2, 3]
[nil, arr, nil].flatten.each_cons(3) do |prev_element, element, next_element|
  p "#{element} is preceded by #{prev_element || 'nil'} and followed by #{next_element || 'nil'}"
end

# "1 is preceded by nil and followed by 2"
# "2 is preceded by 1 and followed by 3"
# "3 is preceded by 2 and followed by nil"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...