Ruby If условие, которое смотрит на все содержимое массива - PullRequest
2 голосов
/ 27 июля 2011

В основном я пытаюсь написать условие if, которое просматривает все содержимое массива, чтобы определить, верно ли это условие.

В основном, я хочу сделать:

SubScale.all.each do |ss|
  if ss.key IN(scales)
    execute this code
  end
end

Где масштабируется в массиве, и я хочу, чтобы код выполнялся, если ss.key является какой-либо записью в этом массиве.

Ответы [ 4 ]

5 голосов
/ 27 июля 2011

Вы ищете Array#include? :

scales.include?(ss.key)
4 голосов
/ 27 июля 2011

Более общий, чем Array#include?, который требует проверки по значению, равен Enumerable#any?:

SubScale.all.each do |ss|
  # Run the code if the value is an exact match
  run_code if scales.include?(ss.key)
end

SubScale.all.each do |ss|
  # Run the code if the block returns a truthy value
  run_code if scales.any?{ |scale| scale.downcase == ss.key.downcase }
end

Наконец, если этоточное соответствие, которое вы хотите, и скорость оказывается проблемой (сначала профиль!), вы можете обменять память на производительность, используя хэш для поиска вашего ключа в O (1) вместо O (n) времени:

scale_lookup = Hash[ scales.map{ |s| [s,true] } ]
SubScale.all.each do |ss|
  run_code if scale_lookup[ss.key]
end
1 голос
/ 27 июля 2011

scale.include? (Ss.key) это то, что вам нужно.

0 голосов
/ 27 июля 2011

Если scales имеет много элементов, как и SubScale.all, я бы предложил создать временный набор (или хэш):

require "set"

scales_set = Set.new(scales)

....each do |ss|
  if scales_set.include?(ss.key)
    ...
  end
end

Это может быть намного быстрее.

PS Hashкажется быстрее, чем установлено:

scales_hash = scales.inject({}) { |h, e| h[e] = true; h }

....each do |ss|
  if scales_hash.has_key?(ss.key)
    ...
  end
end
...