【问题标题】:How to convert a 2D array to a value object in ruby如何将二维数组转换为 ruby​​ 中的值对象
【发布时间】:2017-08-26 00:52:12
【问题描述】:

我有一个二维数组:

a = [["john doe", "01/03/2017", "01/04/2017", "event"], ["jane doe", "01/05/2017", "01/06/2017", "event"]...]

我想将它转换为 ruby​​ 中的值对象。我在这个问题的第二个答案中找到了如何使用哈希 Ruby / Replace value in array of hash 来做到这一点,但不是二维数组。我想将a[0][0] 的值分配给名为"name"a[0][1]"date1"a[0][2]"date2"a[0][3]"event" 的属性。

这就像我想要完成的事情,虽然它不完整,我不知道如何在一个循环中为不同的属性分配多个索引:

class Schedule_info
   arrt_accessor :name, :date1, :date2, :event

   def initialize arr
       #I would like this loop to contain all 4 attr assignments
       arr.each {|i| instance_variable_set(:name, i[0])} 

【问题讨论】:

  • 您的意思是要将此数组数组转换为具有名称、日期等方法的对象数组吗?以便在转换后您可以执行 a[0].name、a[1].event 等?
  • 我最终想做一些类似于这个问题的事情:link 但使用我的二维数组
  • 有人能说明为什么我被否决了吗?
  • 从您的问题中不清楚您到底想要什么。你能给我们一个你想要的样本输出值吗?还是示例数据结构?
  • 在询问我们之前,您也没有表现出任何个人尝试这样做。如果你能证明你所做的一些尝试是无效的,那么你更有可能获得投票。

标签: arrays ruby object


【解决方案1】:

这应该足够简短和干净,没有不必要的元编程:

data = [["john doe", "01/03/2017", "01/04/2017", "event"],
        ["jane doe", "01/05/2017", "01/06/2017", "event"]]

class ScheduleInfo
  attr_reader :name, :date1, :date2, :type

  def initialize(*params)
    @name, @date1, @date2, @type = params
  end

  def to_s
    format('%s for %s between %s and %s', type, name, date1, date2)
  end
end

p info = ScheduleInfo.new('jane', '31/03/2017', '01/04/2017', 'party')
# #<ScheduleInfo:0x00000000d854a0 @name="jane", @date1="31/03/2017", @date2="01/04/2017", @type="party">
puts info.name
# "jane"

schedule_infos = data.map{ |params| ScheduleInfo.new(*params) }
puts schedule_infos
# event for john doe between 01/03/2017 and 01/04/2017
# event for jane doe between 01/05/2017 and 01/06/2017

【讨论】:

  • 除了将散列值转换为字符串之外,您还可以创建一个循环,将所有散列(键和值)放入一个数组中。所以它是一个哈希数组。
  • @EXC3ll3NTrhyTHM:我不会将ScheduleInfo 对象转换为字符串,我只是使用该对象的字符串表示。 schedule_infosScheduleInfo 对象的数组,您可以在它们上调用 name, date1, ...。
【解决方案2】:

试试这个:

class Schedule_info
  arrt_accessor :name, :date1, :date2, :event

  def initialize arr
    @name = []
    @date1 = []
    @date2 = []
    @event = []
    arr.each |i| do
      name << i[0]
      date1 << i[1]
      date2 << i[2]
      event << i[3]
    end
  end

end

【讨论】:

  • 这完成了我试图弄清楚的属性分配
  • @EXC3ll3NTrhyTHM 很高兴听到这个消息!如果这完全回答了您的问题,请将其标记为已接受的答案(通过按检查),以便其他用户能够找到它。谢谢!
【解决方案3】:

听起来你想调用每个数组值对应的属性访问器方法。您使用send 以编程方式调用方法。因此,您需要一个与给定数组中的值相对应的方法名称数组。现在,假设具有您的属性的类称为Data

attrs = [:name, :date1, :date2, :event]
result = a.map do |e|
  d = Data.new
  e.each.with_index do |v, i|
    d.send(attrs[i], v)
  end
  d
end

result 是从给定数组填充的Data 对象数组。

当然,如果您控制 Data 对象的定义,最好的办法是给它一个初始化方法,该方法采用一组值。

【讨论】:

    【解决方案4】:

    您不能将键值对存储在数组索引中。您要么只需要记住数组的第一个索引将具有“名称”并分配a[0][0] = "foo",要么只需将哈希数组用于您想要的键值功能

    2.3.0 :006 > a = []
     => [] 
    2.3.0 :007 > hash1 = {name: "hash1name", date: "hash1date", event: "hash1event"}
     => {:name=>"hash1name", :date=>"hash1date", :event=>"hash1event"} 
    2.3.0 :008 > a << hash1
     => [{:name=>"hash1name", :date=>"hash1date", :event=>"hash1event"}] 
    2.3.0 :009 > hash2 = {name: "hash2name", date: "hash2date", event: "hash2event"}
     => {:name=>"hash2name", :date=>"hash2date", :event=>"hash2event"} 
    2.3.0 :010 > a << hash2
     => [{:name=>"hash1name", :date=>"hash1date", :event=>"hash1event"}, {:name=>"hash2name", :date=>"hash2date", :event=>"hash2event"}] 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-10
      • 2015-10-22
      • 1970-01-01
      • 1970-01-01
      • 2010-11-20
      • 2013-02-21
      相关资源
      最近更新 更多