如何处理函数中传递的负迭代器?

时间:2017-05-19 20:52:27

标签: ruby rotation

我正在使用Ruby中的手动旋转功能。但是我遇到了问题,在一些例子中传递了负面偏移。是否可以从负数迭代到指定的索引(不确定该索引是什么)?

def my_rotate(arr, offset=1)
  if offset < 1 
    for i in offset
      arr.push(arr.shift)
    end
  else 
    for i in 1..offset
      arr.push(arr.shift)
    end
  end  
  arr
end

2 个答案:

答案 0 :(得分:2)

关注您的代码后,您可以使用Array#popArray#unshiftArray#pushArray#shift的对立面):

add_action( 'woocommerce_add_to_cart_validation', 'woo_add_to_cart_validation, 10, 5 );
function woo_add_to_cart_validation( $passed, $product_id ) { 

    //Build timestamp from the potential product values
    $submitStartTime = strtotime( $_POST['wc_bookings_field_start_date_year'] . "-" . $_POST['wc_bookings_field_start_date_month'] . '-' . $_POST['wc_bookings_field_start_date_day'] . " " . $_POST['wc_bookings_field_start_date_time']);
    //Compare with a 30 minute booking.
    $submitEndTime = $submitStartTime + (60 * 30);

    //Verify that no bookings exist (as orders or in cart)
    $booking_ids = WC_Bookings_Controller::get_bookings_in_date_range($submitStartTime, $submitEndTime, $product_id, true);

    if( $booking_ids ) {
        wc_add_notice( __( 'The date/time you selected has already been booked. Please select another.', 'woocommerce-bookings' ), 'error' );
        $passed = false;
    }

    return $passed;
}

注意第5行def my_rotate(array, offset=1) arr = array.dup if offset < 1 for i in 1..offset.abs arr.unshift(arr.pop) end else for i in 1..offset arr.push(arr.shift) end end arr end 的更改能够循环数组,并添加第2行for i in 1..offset.abs以防止原始数组发生变异。

答案 1 :(得分:1)

这几乎就是Array#rotate的做法(在C中)。

<强>代码

class Array
  def my_rotate(n=1)
    n %= self.size
    self[n..-1].concat(self[0,n])
  end
end

<强>实施例

arr = [1,2,3,4]

arr.my_rotate  0   #=> [1,2,3,4]

arr.my_rotate      #=> [2, 3, 4, 1]
arr.my_rotate  1   #=> [2, 3, 4, 1]
arr.my_rotate  4   #=> [1, 2, 3, 4]
arr.my_rotate  5   #=> [2, 3, 4, 1]
arr.my_rotate  9   #=> [2, 3, 4, 1]

arr.my_rotate -1   #=> [4, 1, 2, 3]
arr.my_rotate -4   #=> [1, 2, 3, 4]
arr.my_rotate -5   #=> [4, 1, 2, 3]
arr.my_rotate -9   #=> [4, 1, 2, 3]

<强>解释

该行

n %= self.size

Ruby的解析器扩展到

n = n % self.size

n转换为0self.size - 1之间的整数。此外,它对n的正值和负值都这样做。

该行

self[n..-1].concat(self[0,n])

n的第一个arr元素附加到由arr.size - n的最后arr个元素组成的数组中。然后通过该方法返回结果数组。

如果您不希望将此方法添加到课程Array,您当然可以将其定义为def my_rotate(arr, n)...