Find方法是从数组中返回错误的对象吗?

时间:2016-10-29 22:30:30

标签: arrays ruby object methods enumeration

我正在研究基于文本的冒险游戏的Ruby项目,并且在尝试使用Ruby中的“find”方法时遇到了一个问题。

我有一个所有位置都是实例化的位置类。每个位置都有一组两个坐标,([x,y] = [1,1]),玩家也有自己的坐标集来存储它们实际所在的位置。

班级方法&初始化方法

def self.findLocation(coord, attributeToPrint)
    puts coord.inspect
    puts @@finder.find { coord }.inspect
  end

def initialize(newTitle, newDescription, newCoord)
    @title = newTitle
    @description = newDescription
    @coordinate = newCoord

    @@finder << self
  end

我要做的是将所有位置存储在数组中,并使用类方法打印出位置的标题和描述,方法是使用find方法选择具有匹配坐标的位置给玩家。我当前使用的方法在coord参数中传递了玩家的坐标,并使用find方法检查坐标中的数组(其中包含所有位置对象)。

我发现了许多与此方法相关的问题,但是在这些问题上找到的任何解决方案都没有成功,而且我自己的任何解决方案都没有运气。如果我尝试使用诸如@coordinate == coord之类的比较语句,该方法将只返回nil并且我的当前版本返回一个对象,但只返回数组中第一个并且不返回该位置的对象匹配的@coordinate属性。

我非常感谢对这个问题的任何帮助,因为它是在文本冒险游戏上取得一些进展并允许一些交互性的主要障碍。我确信我正在使用这种方法不正确,并且不理解它是如何工作的,但是在查看它之后枚举器文档并没有给我很多帮助,并且可能有更好的方法在类方法上实现它。 / p>

重现问题

位置等级(必要部分)

class Location
  @@finder = Array.new

  def self.findLocation(coord, attributeToPrint)
    puts coord.inspect
    puts @@finder.find { coord }.inspect
  end

  #Initialise locations here
  def initialize(newTitle, newDescription, newCoord)
    @title = newTitle
    @description = newDescription
    @coordinate = newCoord

    @@finder << self
  end

玩家类(必要部分)

class Player
  def initialize(playerHealth, playerLocation, playerInventory)
    @health = playerHealth
    @location = playerLocation
    @inventory = playerInventory
  end

主要脚本(必要部分)

require_relative '../lib/player'
require_relative '../lib/location'

start = Location.new('Test 1', 'This is test 1.', [0, 0])
start2 = Location.new('Test 2', 'This is test 2.', [1,1])
start3= Location.new('Test 3', 'This is test 3.', [2, 2])
player = Player.new(100, [1,1], ['sword'])

#Input loop
loop do

  Location.findLocation(player.getLocation, 'example')
end

1 个答案:

答案 0 :(得分:1)

您必须指定find与所提供的值匹配存储记录的方式。具体来说,您需要将coord与记录的坐标进行比较。要访问记录的坐标,您需要一个getter方法。

class Location

  def self.findLocation(coord, attributeToPrint)
    puts coord.inspect
    puts @@finder.find { |location| location.coord == coord }.inspect
  end

  def coord
    @coord
  end

end  

find的工作方式是它为数组中的每个实例执行块,返回结果为'truthy'的第一个数组元素(即不是nil而不是false)。执行{coord}时,块会立即返回coord值。 coord不是nil而不是false,因此选择了第一条记录。当你@coord == coord @coord时,title在类级别是未定义的(它是零),因此对于所有记录,比较都是假的,因此没有选择记录,因此你的结果为零。

要打印特定属性(例如,class Location def self.findLocation(coord, attributeToPrint) puts coord.inspect found_location = @@finder.find { |location| location.coord == coord } puts found_location.send(attributeToPrint) if found_location end def coord @coord end def title @title end end ),您还可以使用getter方法访问该属性。然后将该方法发送到该对象。

Location.findLocation([1,1], 'title')

所以现在你可以做......

class Location

  def self.findLocation(coord)
    @@finder.find { |location| location.coord == coord }
  end

  def coord
    @coord
  end

  def title
    @title
  end

end 

...然而

让findLocation只负责返回对象,然后在方法之外输出属性......单一责任原则......

player_location = Location.findLocation([1,1])
puts player_location.title if player_location

所以现在你可以做......

var Hello = <h1>
            Hello, {user}!
            </h1>