This question already has answers here:
Is there some kind of unseen Array termination in Ruby?
(3 answers)
Closed 8 years ago.
While going over the Array class from the Ruby 2.0.0 docs, I noticed something I can't explain. The following is a direct example from the Ruby Docs:
a = [ "a", "b", "c", "d", "e" ]
a[6, 1] #=> nil
a[5] #=> nil
a[5, 1] #=> []
Could some one explain to me why a[5, 1] has the output [ ]?
The semantics of [] are the same as for slice when two integers are provided. As explained in http://ruby-doc.org/core-2.0/Array.html#method-i-slice, when the first integer points to the end of the array, the empty array will be returned.
Related
This question already has answers here:
Measure the distance between two strings with Ruby?
(7 answers)
Closed 6 years ago.
I was trying to find the difference in letters between two strings.
For example, if I put the word ATTGCC and GTTGAC, the difference would be 2 since A and G and C and G are not the same characters.
class DNA
def initialize (nucleotide)
#nucleotide = nucleotide
end
def length
#nucleotide.length
end
def hamming_distance(other)
self.nucleotide.chars.zip(other.nucleotide) { |a,b| a == b }.count
end
protected
attr_reader :nucleotide
end
dna1 = DNA.new("ATTGCC")
dna2 = DNA.new("GTTGAC")
puts dna1.hamming_distance(dna2)
The method hamming_distance doesn't really work as it gives a wrong argument type String (must respond to :each) (TypeError)
Assuming the strings are of the same length, you can split them, zip them, and find how many pairs match:
string1 = "RATTY"
string2 = "CATTI"
string1.chars.zip(string2.chars).select { |a,b| a == b }.count
The .chars produces an array of the characters in the string ("RATTY" => ["R", "A", "T", "T", "Y"])
The .zip call merges the two arrays together into a an array of pairs, ["R", "A", "T"].zip(["C", "A", "T"]) => [ ["R", "C"], ["A", "A"], ["T", "T"]]
The select filters out the pairs where the values aren't equal
The count returns the number of pairs matched by select
You can find the number of non-matching pairs by negating the selection
This question already has answers here:
Array slicing in Ruby: explanation for illogical behaviour (taken from Rubykoans.com)
(10 answers)
Closed 7 years ago.
For a four-element array, [4] returns nil, but [4, 0] returns an empty array.
array = [:peanut, :butter, :and, :jelly]
array[4] # => nil
array[4, 0] # => []
array[5] # => nil
array[5, 0] # => nil
Why would [4, 0] not return nil just like [5, 0]?
Answer from Array slicing in Ruby: looking for explanation for illogical behaviour (taken from Rubykoans.com) =>
Graphical Explination of WHats Happening
It's a special case. From the official docs (the italics are mine):
For start and range cases the starting index is just
before an element. Additionally, an empty array is returned when the
starting index for an element range is at the end of the array.
a = [ "a", "b", "c", "d", "e" ]
# ...
# special cases
a[5] #=> nil
a[6, 1] #=> nil
a[5, 1] #=> []
This question already has answers here:
What is the easiest way to push an element to the beginning of the array?
(7 answers)
Closed 8 years ago.
What is the best way to prepend to an array in Ruby. Perhaps something similar to Python's list.insert(0, 'foo')?
I'd like to be able to add an element to a Ruby array at the 0 position and have all other elements shifted along.
array = ['b', 'c']
array.unshift('a')
p array
=> ['a', 'b', 'c']
As Scott G has pointed out in the comments, as of Ruby 2.5.0 #prepend has been added as an alias for #unshift.
Another way than Steve's answer
array = ['b', 'c']
array = ['a'] + array #["a", "b", "c"]
array = ["b", "c"]
array.insert(0, "a", "a") # => ["a", "a", "b", "c"]
This question already has answers here:
Array slicing in Ruby: explanation for illogical behaviour (taken from Rubykoans.com)
(10 answers)
Closed 9 years ago.
array = [:peanut, :butter, :and, :jelly]
Why does array[4,0] return [] and array[5,0] returns nil?
According to Array#[] documentation:
an empty array is returned when the starting index for an element
range is at the end of the array.
Returns nil if the index (or starting index) are out of range.
a = [ "a", "b", "c", "d", "e" ]
a[2] + a[0] + a[1] #=> "cab"
a[6] #=> nil
a[1, 2] #=> [ "b", "c" ]
a[1..3] #=> [ "b", "c", "d" ]
a[4..7] #=> [ "e" ]
a[6..10] #=> nil
a[-3, 3] #=> [ "c", "d", "e" ]
# special cases
a[5] #=> nil
a[6, 1] #=> nil
a[5, 1] #=> []
a[5..10] #=> []
I have
strings = ["aaa", "bb", "ccc", "ddd", "e", "ff", "rrrrrrrr", "tttttttt", "a"]
I want to group the strings in the array so that each element is no longer then 5 and not shorter then 9. The strings have to maintain their order in the array.
EDIT: Sorry for confusion, yes - at least 5 and at most 9.
the outcome I am looking for is:
result = ["aaabbbccc", "dddeff", "rrrrrrrr", "tttttttta"]
Since your question was specified in a rather confusing way, this is the best I could come up with.
strings.inject(['']) { |a, s| a.last.size + s.size <= 9 ? a.last << s : a << s ; a }
#=> ["aaabbccc", "dddeff", "rrrrrrrr", "tttttttta"]