Ruby 'Range.last' does not give the last value. Why?
This is by design. The Ruby 2.0 documentation is more specific:
Note that with no arguments
last
will return the object that defines the end of the range even ifexclude_end?
istrue
.(10..20).last #=> 20
(10...20).last #=> 20
(10..20).last(3) #=> [18, 19, 20]
(10...20).last(3) #=> [17, 18, 19]
Ruby array only storing last value, not all values
In your index
action, change the line:
@products = Product.where(category_id: category.id).take(1)
To:
@products << Product.where(category_id: category.id).take(1)
UPDATE:
Since take(1)
will return an object in array, you need to simply change it to:
@products << Product.where(category_id: category.id).take
Why is (10..20).last the same as (10...20).last
I'll answer your question with a question: what is the last value of 0.0...1.0
?
In general, not every Range is enumerable. For such ranges with an excluded end, there really is no meaningful last
value other than the value used to define the end of the range.
Note also that you can enumerate inclusive ranges where last
is not the last value enumerated!
(0..3.2).to_a.last
# 3
(0..3.2).last
# 3.2
(0..Float::INFINITY).to_a.last
# don't wait up for this one
The motivation of the design is that "the value used to define the end of a range" is not identical to "the last value enumerated by a range". last
gives you the former.
Ruby - Last value of a isn't printed
return
controls program flow, calling it will exit the current method and pass the value of a
into whatever expression called it.
Usually you would not write a method with an unconditional return
and more code afterward, because that code is not reachable. The puts
in your example will never be called. Just move it to before the return
expression if you want it to run.
What was the last version of Ruby where array range never returned nil?
I think it's 1.2.x.
The oldest Ruby documentation I could find was was for Ruby 1.2. It says this about Array#[]
:
self[start..end]
Returns an array containing the objects from start to end, including both ends. if end is laeger[sic] than the length of the array, it will be rounded to the length. And if start is larger than end, this method returns empty array (
[]
).
So in 1.2, it always returns an array.
The next-oldest documentation I could find was for Ruby 1.6. It says:
arr[anInteger] -> anObject or nil
arr[start, length] -> aSubArray or nil
arr[aRange] -> aSubArray or nilElement Reference-Returns the element at index anInteger, or returns a subarray starting at index start and continuing for length elements, or returns a subarray specified by aRange. Negative indices count backward from the end of the array (-1 is the last element). Returns
nil
if any indices are out of range.
So that narrows it down a lot. Then I decided to go straight to the source. In Ruby 1.2, Array#[]
is called ary_aref
in array.c. If the argument is a range, it calls beg_len
to get the beginning index and the length of the subsequence, and then calls ary_subseq
with those arguments. Long story short, ary_subseq
always returns an array, never nil
.
Next I tried Ruby 1.3, where Array#[]
is now called rb_ary_aref
. Lo and behold, we see this (406–414):
/* check if idx is Range */
switch (rb_range_beg_len(arg1, &beg, &len, RARRAY(ary)->len, 0)) {
case Qfalse:
break;
case Qnil:
return Qnil;
default:
return rb_ary_subary(ary, beg, len);
}
I think that speaks for itself: If the argument is out of range, return nil
.
Since I'm terrible at C, I went and checked the Ruby 1.6 source (since we know from the documentation that it has the nil
behavior) and found that its implementation is the same.
I'm pretty confident, then, that Ruby 1.2.x is the last Ruby that returned an empty array, and 1.3.x is the first Ruby that returned nil
.
Ruby 1.2, by the way, was released in 1998.
Last element of the ruby array is nil
Array.new
creates a new array, filling it with the quantity of elements you specified. Array.new(3)
is the same as [nil, nil, nil]
. Array.new(2, 'a')
is the same as ['a', 'a']
.
You then use array.insert
which adds instead of replaces the elements. You could use array[i-1] = gets.chomp()
to set the values, but there's really no reason to initialize the array this way at all.
A "more Ruby" way to write this all would be:
puts 'How many stocks do you want to track ?'
num_stocks = gets.chomp
puts "Please enter #{num_stocks} stock symbols: "
array = 1.upto(num_stocks.to_i).map do
gets.chomp
end
puts "Stock symbols entered ... #{array}"
EDIT:
Also, it’s worth mentioning that in Ruby, arrays are not a fixed size. You can add and remove elements from them as you please. If I had to guess, you’re used to languages like C, where you have to define the size of your array up front and then it’s just that size forever (that’s what I’m guessing you were trying to do anyways).
And another thing, in Ruby it’s not very common to use Array.new
. Most times people just define an array by typing an array literal.
array = [1,2,3]
A ruby array is more like a List in other languages. It supports push
(though <<
is a more common method for adding to an array), pop
, and other list-like features.
Ruby for loop only using last value
The problem is that you are re-assigning @facilities
on each iteration of the loop. I think you want something more like:
@facilities = []
for a in @activities
@facilities << Facility.find(a.facility_id)
end
This might be better written as
@facilities = @activities.map {|a| Facility.find(a.facility_id) }
But, preferably, you've defined an association for :facility
@facilities = @activities.map {|a| a.facility}
Ruby recursion through array not getting to last value
It's the second-last ")" that return immediately before it reach the last ")". Note that return in lambda will also return from the parent function. This code should work:
UPDATE: I think an array is not sufficient to get the data since it lacks the link between its member to the parent container. A tree data structure is required to store the information and a child can link with parent through function parent here. I rewrite the code, and this returns result as expected:
class Node
attr_accessor :parent, :children, :values
def initialize
@children = []
@parent = nil
@values = []
end
def add_child(child)
child.parent = self
@children << child
end
def add_value(value)
@values << value
end
def to_a
result = values.clone
@children.each do |child|
result << child.to_a
end
result
end
end
def set_execution_order(value)
_set_execution_order = lambda do |tokens, node|
token = tokens.shift
case token
when nil
return node
when "("
child = Node.new
node.add_child(child)
_set_execution_order[tokens, child]
when ")"
_set_execution_order[tokens, node.parent]
else
node.add_value(token)
return _set_execution_order[tokens, node]
end
end
root = Node.new
_set_execution_order[value, root]
root
end
set_execution_order(["(", 1, "(", 2, 3, ")", 4, "(", 5, 6, ")", ")"]).to_a #returns => [[1, 4, [2, 3], [5, 6]]]
All but last element of Ruby array
Perhaps...
a = t # => [1, 2, 3, 4]
a.first a.size - 1 # => [1, 2, 3]
or
a.take 3
or
a.first 3
or
a.pop
which will return the last and leave the array with everything before it
or make the computer work for its dinner:
a.reverse.drop(1).reverse
or
class Array
def clip n=1
take size - n
end
end
a # => [1, 2, 3, 4]
a.clip # => [1, 2, 3]
a = a + a # => [1, 2, 3, 4, 1, 2, 3, 4]
a.clip 2 # => [1, 2, 3, 4, 1, 2]
How do I destructure a range in Ruby?
No, Until I am proven incorrect by Cary Swoveland, Weekly World News or another tabloid, I'll continue believing without any evidence that the answer is "no"; but it's easy enough to make.
module RangeWithBounds
refine Range do
def bounds
[self.begin, self.end]
end
end
end
module Test
using RangeWithBounds
r = (1..10)
b, e = *r.bounds
puts "#{b}..#{e}"
end
Then again, I'd just write "#{r.begin.number_to_currency}..#{r.end.number_to_currency}"
in the first place.
Related Topics
Running Selenium::Webdriver::Firefox Inside Xvfb from Ruby as Non-Root User
Rmagick Error After Installing Os X Mavericks
Ruby or Rails Sort on Two/Multiple Date Fields
Rails 3 and PDFkit. How to Specify Page Size
Is There a Groovy Equivalent of the Ruby Timeout Module
Activerecord_Postgis_Adapter: Undefined Method 'Point' for Nil:Nilclass
Rails 7 Signup Form Doesn't Show Error Messages
How to Capture a Part of a Screen Using Ruby on Windows
Ruby on Rails Active Admin Has_Many Changing Dropdown to Use a Different Column
Get Pry to Display Characters Like [äöüßÄÖÜß] (Utf-8 Encoding)? (Possibly Windows-Specific Issue)
Best Way to Find_Or_Create_By_Id But Update the Attributes If the Record Is Found
Handle Check Box Forms with an ':Has_Many :Through' Record Association
Net-Ssh and Remote Environment
Accessing the Child Instance in a Rabl Template
What's the Difference Between the Ruby Irb Prompt Modes