简体   繁体   中英

Iterating through an array to create if statements in ruby

I have the following arrays of prices and dates.

prices = [60, 70, 80]

dates = [earliest_date, middle_date, latest_date]

Assuming the arrays are equal length, how can I iterate through the arrays to create an if statement along these lines for variable array lengths?

if Date.current < dates[0]
  price = prices[0]
elsif Date.current < dates[1]
  price = prices[1]
...
else
  price = some_default_price_value
end

尝试这个:

price = prices.find.with_index {|_, i| Date.current < dates[i] } || DEFAULT_PRICE

You can have something of this sort:

for i in 0..prices.size
  if Date.current < dates[i]
    price = prices[i]
    break
end
price = prices.zip(dates).find{|_, date| Date.current < date} &.first \
|| some_default_price_value

&. is to make first safe in case an element satisfying the condition is not found.

You can use Enumerable#find with an argument that is a lambda .

Code

require 'date'

def price(prices, default_price, dates, curr_date)
  dates.zip(prices).find(ifnone=->{ [nil, default_price] }) { |d,_| curr_date < d }.last
end

Examples

prices = [60, 70, 80]
default_price = 90
dates = [Date.today-1, Date.today+1, Date.today+3]
  #=> [#<Date: 2016-02-16 ((2457435j,0s,0n),+0s,2299161j)>,
  #    #<Date: 2016-02-18 ((2457437j,0s,0n),+0s,2299161j)>,
  #    #<Date: 2016-02-20 ((2457439j,0s,0n),+0s,2299161j)>] 

price(prices, default_price, dates, Date.today-2) #=> 60
price(prices, default_price, dates, Date.today)   #=> 70 
price(prices, default_price, dates, Date.today+2) #=> 80
price(prices, default_price, dates, Date.today+4) #=> 90

Other ways

Here are two other ways that have not been mentioned:

#1 Use an inline rescue

def price(prices, default_price, dates, curr_date)
  dates.zip(prices).find { |d,_| curr_date < d }.last rescue default_price
end

#2 Add a higher limit

def price(prices, default_price, dates, curr_date)
  (dates+[curr_date+1]).zip(prices+[default_price]).
    find { |d,_| curr_date < d }.last
end

assuming the size will be same for both, and the order doesn't matter as well.

prices = [60, 70, 80]
dates = [earliest_date, middle_date, latest_date]
prices.each_with_index do |p,index|
   puts "price: #{p}"
   puts "Date: #{dates[index]}"
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM