Ruby arrays can be indexed backwards

Discussion in 'Learning Ruby and RGSSx' started by Tsukihime, Dec 6, 2013.

  1. Tsukihime

    Tsukihime Veteran Veteran

    Messages:
    8,230
    Likes Received:
    3,062
    Location:
    Toronto
    First Language:
    English
    For those that are not familiar with the concept of "negative indices" that is common in a couple languages, you can index ruby arrays using positive and negative numbers

    Code:
    arr = [1,2,3,4,5]p arr[0]  # 1p arr[1]  # 2p arr[2]  # 3p arr[-1] # 5p arr[-2] # 4
     
    #1
    Galenmereth and mahan like this.
  2. Yato

    Yato (aka Racheal) Veteran

    Messages:
    826
    Likes Received:
    344
    Location:
    Canada
    That's interesting. So arr[-1] is functionally the same as arr[arr.length - 1] then? That certainly can make the code look nicer :3
     
    #2
  3. mahan

    mahan no lack of courage! Veteran

    Messages:
    94
    Likes Received:
    8
    Location:
    Philippines
    First Language:
    English
    usually when I need to traverse the array reversely, I reverse the array itself by using .reverse  then loop on it. well its just a another suggestion because I easily get confused with negative numbers  ;_;  I really hate math XD
     
    Last edited by a moderator: Dec 6, 2013
    #3
  4. Dr.Yami

    Dr.Yami 。◕‿◕。 Developer

    Messages:
    994
    Likes Received:
    736
    Location:
    Finland
    First Language:
    Vietnamese
    Primarily Uses:
    Other
    I don't like that negatively call though, it makes me feel like "calling the previous address" *lol*
     
    #4
  5. estriole

    estriole Veteran Veteran

    Messages:
    1,030
    Likes Received:
    334
    First Language:
    indonesian
    or calling previous boy/girlfriend?? :D .
     
    #5
  6. Galenmereth

    Galenmereth I thought what I'd do was Veteran

    Messages:
    2,206
    Likes Received:
    1,917
    Location:
    Norway
    First Language:
    English
    Primarily Uses:
    RMMV
    You can also define an array of strings like this:

    %w(first second third fourth)

    Which is equal to:

    ["first", "second", "third", "fourth"]
     
    #6
  7. IceDragon

    IceDragon Elder Cookie Dragon Veteran

    Messages:
    73
    Likes Received:
    60
    Location:
    Jamaica
    First Language:
    English
    Primarily Uses:
    N/A
    Well Ruby has a lot of sugar in it (beware diabetics)

    As Tsukihime mentioned, you can index an Array backwards.

    array = [1, 2, 3]array[-1] # => 3# same as using Enumerable#lastarray.last #=> 3It is encouraged to use array.last instead of array[-1] for reading clarity.Array's may also be "sub-sampled"

    array = [1, 2, 3, 4, 5, 6]# starting at index 0, grab the next 3 elementsarray[0, 3] # => [1, 2, 3]# this even works with negative indeciesarray[-2, 2] # => [5, 6]# you may also use a Range insteadarray[0...3] # => [1, 2, 3]# note the use of 3 periods rather than 2array[0..3] # => [1, 2, 3, 4]%w and %W (as mentioned by Galenmereth)
    Code:
    # there is a difference between the two# at a glance they produce the same output%W(foo bar zan tan lan) #=> ["foo", "bar", "zan", "tan", "lan"]%w(foo bar zan tan lan) #=> ["foo", "bar", "zan", "tan", "lan"]# however when inlining they become completely differentwee = "lee"%W(foo bar zan tan lan #{wee}) #=> ["foo", "bar", "zan", "tan", "lan", "lee"]%w(foo bar zan tan lan #{wee}) #=> ["foo", "bar", "zan", "tan", "lan", "#{wee}"]
    This is also the same rule applied to "" and ''%Q() is equivalent to ""

    %q() is equivalent to ''

    Both are used to produce a String

    place = "your place"%Q(Well this is ackward.I think my money is finished and I have nowhere to go.Will you let me stay at #{place}.) #=> "Well this is ackward\nI think my money is finished and I have nowhere to go.\nWill you let me stay at your place."%q(Well this is ackward.I think my money is finished and I have nowhere to go.Will you let me stay at #{place}.) #=> "Well this is ackward\nI think my money is finished and I have nowhere to go.\nWill you let me stay at #{place}."And Symbolization!
    Code:
    %s(my awesomeness cannot be contained) #=> :"my awesomeness cannot be contained""my awesomeness cannot be contained".to_sym #=> :"my awesomeness cannot be contained"
    Regular Expressions
    Code:
    %r((\w+)\s(\S+))
    System Calls
    Code:
    %x(echo Gimme teh world!)`echo yeah this works as well`system("echo go ahead, knock yourself dead!")
    Warning: try to avoid system calls for portable code.You don't have to use ( ) as a demiliter with %Q, %q, %W, %w, %s, %r it also accepts quite a lot different ones

    For this example, I'll only be using %w

    %w(some words that should make sense) #=> ["some", "words", "that", "should", "make", "sense"]%w<some words that should make sense> #=> ["some", "words", "that", "should", "make", "sense"]%w{some words that should make sense} #=> ["some", "words", "that", "should", "make", "sense"]%w[some words that should make sense] #=> ["some", "words", "that", "should", "make", "sense"]%w/some words that should make sense/ #=> ["some", "words", "that", "should", "make", "sense"]# and some really odd ones%w!some words that should make sense! #=> ["some", "words", "that", "should", "make", "sense"]%w@some words that should make sense@ #=> ["some", "words", "that", "should", "make", "sense"]%w$some words that should make sense$ #=> ["some", "words", "that", "should", "make", "sense"]%w%some words that should make sense% #=> ["some", "words", "that", "should", "make", "sense"]# this works with ~ ! @ # $ % ^ & * and a some others, just try em yourselfSo you can go out and feel like a baws using anything that floats your boatbut since I'm a guy of tradition I'll stick with my round/curly/square brackets

    Oh and don't forget Heredocs!

    my_doc = <<__EOF__So you can use this just like %Q()__EOF__my_doc2 = <<YOU_CAN_USE_ALMOST_ANYTHINGHowever I find heredocs to be a pain in the ass because of there sensitivity to spacingYOU_CAN_USE_ALMOST_ANYTHINGMany ways to peel an Apple.Oh and lazy initialization.

    def my_funct @my_variable ||= begin some_super_time_wasting_operation_that_really_only_needs_to_be_done_once endendmy_funct #=> valuemy_funct.equal?(my_funct) # true # its the same result# that above is equivalent to this:def my_funct if !@my_variable @my_variable = some_super_time_wasting_operation_that_really_only_needs_to_be_done_once end @my_variableendArray binary operators
    Code:
    # binary and[1, 2, 3] & [2, 3] #=> [2, 3][1, 2, 3] & [2, 4] #=> [2]# binary or[1, 2, 3] | [2, 3] #=> [1, 2, 3][1, 2, 3] | [2, 4] #=> [1, 2, 3, 4]
    Symbol shorthand for HashThis only works with Symbols

    Code:
    # normal{ :my_symbol => 0 }# shorthand{ my_symbol: 0 }
    Object to Boolean
    Code:
    !!obj
    Hash method parameters
    Code:
    def detonate(options)  meta = options[:meta] || "detonate"  should_explode = !!options[:explode]  range = options[:range] || 1  min_range = options[:min_range] || 0  do_detonation_hereenddetonate(meta: "KABOOM", explode: true, range: 5, min_range: 3)
    Integer#next and Integer#pred
    Code:
    1.next #=> 25.pred #=> 4
    Integer#times
    Code:
    5.times do   puts "Hello World!"end
    Symbol#to_proc
    Code:
    [1, 2, 3].map(&:next) #=> [2, 3, 4]# something like thislist_of_sprites.each(&:update) # replaces this:for sprite in list_of_sprites  sprite.updateend# and this:list_of_sprites.each do |sprite|  sprite.updateend
    Enumerable Abuse
    Code:
    enum = 10.times enum.next #=> 0enum.next #=> 1# .. several calls later ..enum.next #=> StopIteration: iteration reached an end10.times.map { |i| i ** 2 } # => [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]#class Numeric   def sqr ; self * self ; end  def negative? ; self < 0 ; endend[-1, -4, 1, 6, 7, -1].select(&:negative?).map(&:sqr).map(&:succ).tap { |array| array.replace(array.zip(array.map(&:sqr))) } #=> [[2, 4], [17, 289], [2, 4]]# okay I'll admit that last one is me abusing ruby's method chaining
    Okay I'll stop now :x
     
    Last edited by a moderator: Dec 8, 2013
    #7
    Evgenij, Zeriab and Galenmereth like this.
  8. Galenmereth

    Galenmereth I thought what I'd do was Veteran

    Messages:
    2,206
    Likes Received:
    1,917
    Location:
    Norway
    First Language:
    English
    Primarily Uses:
    RMMV
    Excellent post IceDragon! I'd like to expand on the Hash method parameters with another way of setting default values, which can be more accessible:

    def explode(options) # Setting default values  options = {    meta: "KABOOM!",    explode: true,    range: 5,    min_range: 0  }.merge(options)    do_detonation_hereend# Then calling it with only meta and min_range set, having the rest set to the above defaultsexplode(meta: "KABLAM!", min_range: 3).merge here overwrites the default params with only those that are received through the method call
     
    Last edited by a moderator: Dec 8, 2013
    #8
    IceDragon likes this.

Share This Page