-1

2D 配列をコンソールに出力しようとしています。この質問の最後にある目的の出力に示されているように、配列内の情報を適切にフォーマットする必要があります。私の配列は次のように作成されます(インスタンスはFamilyMemberクラスから作成されます):

#family_members.rb

class FamilyMember

attr_accessor :name, :sex, :status, :age
def initialize (name, sex, type, role, age)
   @name = name
   @sex = sex
   @type = type
   @role = role
   @age = age
end

end

# Below, an array is created called fm; instances of the class are then instantiated within the array elements
fm = {}
fm[1] = FamilyMember.new('Andrew','Male', 'Child', 'Son' , '27' )
fm[2] = FamilyMember.new('Bill','Male', 'Parent', 'Father' , '63' )
fm[3] = FamilyMember.new('Samantha','Female', 'Parent', 'Mother' , '62' )
fm[4] = FamilyMember.new('Thomas','Male', 'Child', 'Dog' , '10' )
fm[5] = FamilyMember.new('Samantha', 'Female', 'Child', 'Dog' , '4' )

配列の内容を文字列としてフォーマットされたコンソールに出力できるようにしたいと考えています。これを 2 つの方法で実行できるようにする必要がありeachますdo

私が試みたこと(以前のSOの質問に触発された):

def eacharray(an_array)
  an_array.each do |inner|
      puts inner.join(" ")
  end
end

eacharray(fm)

ただし、上記の出力は次のとおりです。

1 #<FamilyMember:0x000000027e7d48>
2 #<FamilyMember:0x000000027e7c58>
3 #<FamilyMember:0x000000027e7b68>
4 #<FamilyMember:0x000000027e7a78>
5 #<FamilyMember:0x000000027e7988>

eachおよび?を使用して適切にフォーマットされた 2D 配列要素を出力するにはどうすればよいdoですか。どんな助けでも感謝します。ありがとう。

理想的には、私の出力は次のようになります。

Family Member   Name     Sex     Type    Role    Age
1               Andrew   Male    Child   Son     27
2               Bill     Male    Parent  Father  63
3               Samantha Female  Parent  Mother  62 
4               Thomas   Male    Child   Dog     10
5               Samantha Female  Child   Dog     4 
4

3 に答える 3

7

固定形式 (各フィールドの最大データ幅に応じて動的に形式を構築できます) に満足している場合は、次のように記述できます。

class FamilyMember
  attr_accessor :name, :sex, :type, :role, :age
  def initialize (*args)
    @name, @sex, @type, @role, @age = args
  end
end

fm = []
fm << FamilyMember.new( 'Andrew',   'Male',   'Child',  'Son' ,    '27' )
fm << FamilyMember.new( 'Bill',     'Male',   'Parent', 'Father',  '63' )
fm << FamilyMember.new( 'Samantha', 'Female', 'Parent', 'Mother',  '62' )
fm << FamilyMember.new( 'Thomas',    'Male',  'Child',  'Dog' ,    '10' )
fm << FamilyMember.new( 'Samantha', 'Female', 'Child',  'Dog' ,     '4' )

format = '%-15s %-8s %-7s %-7s %-7s %s'
puts format % ['Family Member', 'Name', 'Sex', 'Type', 'Role', 'Age']
fm.each_with_index do |member, i|
  puts format % [ i+1, member.name, member.sex, member.type, member.role, member.age ]
end

出力

Family Member   Name     Sex     Type    Role    Age
1               Andrew   Male    Child   Son     27
2               Bill     Male    Parent  Father  63
3               Samantha Female  Parent  Mother  62
4               Thomas   Male    Child   Dog     10
5               Samantha Female  Child   Dog     4

を使用することもできますがfor ... in、これは実際にはほとんど同じループにコンパイルされ、eachイテレータを使用します。

i = 0
for member in fm do
  i += 1
  puts format % [ i, member.name, member.sex, member.type, member.role, member.age ]
end

または、ほとんどの Ruby プログラマーが忘れているプリミティブwhileまたはループ構造を使用できます。untilRuby はイテレータを使用することでより表現力豊かになります。

i = 0
while member = fm[i] do
  i += 1
  puts format % [ i, member.name, member.sex, member.type, member.role, member.age ]
end

doこれらの最後の例の両方からを省略できることに注意してください。式の後に改行 (またはセミコロン) がある限り、whileRuby は問題なく理解します。

于 2013-09-28T15:43:09.100 に答える
1

FamilyMember のようなクラスは、Struct を使用して最も簡単に構築できます。結果は単なるクラスですが、いくつかの追加機能があります。

FamilyMember = Struct.new(:name, :sex, :type, :status, :age)
fm = []
fm << FamilyMember.new('Andrew','Male', 'Child', 'Son' , '27' )
fm << FamilyMember.new('Bill','Male', 'Parent', 'Father' , '63' )

puts FamilyMember.members.map(&:capitalize).join("\t") #members gives you the names of all methods
fm.each{|fam_member|puts fam_member.values.join("\t")} #another feature.

出力:

 Name   Sex Type    Status  Age
 Andrew Male    Child   Son 27
 Bill   Male    Parent  Father  63

並べただけ…

于 2013-09-28T15:46:57.440 に答える