Jinn
Jinn

Reputation: 111

Ruby: replacing a matching element in a multidimensional array?

Could someone tell me how I can achieve replacing an element in this 2D array? I tried each, include and replace and wasn't able to figure out where I am going wrong. Thank you in advance for any help.

class Lotto

  def initialize
    @lotto_slip = Array.new(5) {Array(6.times.map{rand(1..60)})}
  end

  def current_pick
    @number = rand(1..60).to_s
    puts "The number is #{@number}."
  end

  def has_number
    #prints out initial slip
      @lotto_slip.each {|x| p x}

    #Prints slip with an "X" replacing number if  is on slip
    #Ex: @number equals 4th number on slip  --> 1, 2, 3, X, 5, 6
      @lotto_slip.each do |z|
      if z.include?(@number)
          z = "X"
          p @lotto_slip
      else
          z = z
          p @lotto_slip
      end
    end  
  end
end



test = Lotto.new
test.current_pick
test.has_number

Upvotes: 0

Views: 443

Answers (2)

daremkd
daremkd

Reputation: 8424

Let me know if this works out (tried to reduce the variations from 1 to 10 in order to be able to test easier):

class Lotto

  def initialize
    @lotto_slip = Array.new(5) {Array(6.times.map{rand(1..10)})}
  end

  def current_pick
    @number = rand(1..10)
    puts "The number is #{@number}."
  end

  def has_number
    #prints out initial slip
    @lotto_slip.each {|x| p x}

    #Prints slip with an "X" replacing number if  is on slip
    #Ex: @number equals 4th number on slip  --> 1, 2, 3, X, 5, 6
    @lotto_slip.each do |z|
      if z.include?(@number)
        p "#{@number} included in #{z}"
        z.map! { |x| x == @number ? 'X' : x}
      end
    end
    @lotto_slip
  end
end



test = Lotto.new
test.current_pick
p test.has_number

The problems I saw with your code are:

  • You don't need the to_s for this line @number = rand(1..60).to_s, else how are you going to compare the numbers produced by the array with an actual string?

  • You need to re-generate the array instead of re-assigning, that's why I've replaced all of that code with z.map! { |x| x == @number ? 'X' : x} which basically re-generates the entire array.

Upvotes: 1

Jaugar Chang
Jaugar Chang

Reputation: 3196

Not necessary iterate with each, use map:

@lotto_slip = Array.new(5) {Array(6.times.map{rand(1..60)})}
#=> [[25, 22, 10, 10, 57, 17], [37, 4, 8, 52, 55, 7], [44, 30, 58, 58, 50, 19], [49, 49, 24, 31, 26, 28], [24, 18, 39, 27, 8, 54]]

@number = 24
@lotto_slip.map{|x| x.map{|x| x == @number ? 'X' : x}}
#=> [[25, 22, 10, 10, 57, 17], [37, 4, 8, 52, 55, 7], [44, 30, 58, 58, 50, 19], [49, 49, "X", 31, 26, 28], ["X", 18, 39, 27, 8, 54]]

Upvotes: 1

Related Questions