🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
標準出力

標準出力(stdout)は、プログラムが標準的に用いるデータ出力元。標準出力に書き込み要求を発行しすることにより、ディスプレイ装置にデータを表示することができます。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Q&A

解決済

1回答

1007閲覧

Goで列を揃えて出力したい

hizuh

総合スコア14

標準出力

標準出力(stdout)は、プログラムが標準的に用いるデータ出力元。標準出力に書き込み要求を発行しすることにより、ディスプレイ装置にデータを表示することができます。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

0グッド

1クリップ

投稿2019/11/11 14:42

編集2019/11/12 16:16

Goで列を揃えて出力する方法を教えてください。

下記のコードを実行した場合、
サンプルソース

go

1package main 2 3import ( 4 "fmt" 5) 6 7type Cell struct { 8 key string 9 value int 10} 11 12type Row struct { 13 cells []Cell 14} 15 16func main() { 17 row1 := Row{ 18 []Cell{ 19 Cell{"a", 1}, 20 Cell{"b", 2}, 21 Cell{"c", 3}, 22 }, 23 } 24 25 row2 := Row{ 26 []Cell{ 27 Cell{"a", 1}, 28 Cell{"b", 2}, 29 Cell{"c", 3}, 30 Cell{"d", 4}, 31 }, 32 } 33 34 row3 := Row{ 35 []Cell{ 36 Cell{"a", 1}, 37 Cell{"c", 3}, 38 Cell{"d", 4}, 39 }, 40 } 41 42 hoge := []Row{row1, row2, row3} 43 44 for _, r := range hoge { 45 for _, c := range r.cells { 46 fmt.Printf("%s,", c.key) 47 48 } 49 fmt.Println() 50 51 for _, c := range r.cells { 52 fmt.Printf("%d,", c.value) 53 } 54 fmt.Println() 55 } 56} 57

出力結果は、

text

1a,b,c, 21,2,3, 3a,b,c,d, 41,2,3,4, 5a,c,d, 61,3,4,

となりますが、
次のように、

  • 1行目は、row1, row2, row3 に存在するすべての key を出力
  • 2行目以降は、ヘッダの key に応じた値を出力

とし、次のような結果を期待しています。

text

1a,b,c,d, 21,2,3,, 31,2,3,4, 41,,3,4,

どのようなコードにすれば、列を揃えて出力することができるのでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

cellsの定義型「[]Cell」はスライスなので、省略したセルはそのセルの存在そのものがない扱いになります。
つまり「1,2,3,4」の2を省略すればただの「1,3,4」という3つの値を持つスライスになります。

なのであなたの書いたスライスをコンマ区切りで順に出力だと「1,3,4」になるのは当然なのです

ここであなたが期待しているのは「1,,3,4」ということなので、
データ初期化の段階で値のないセルにも初期値(値が空のCell)を与えれば良いということです。

あと、キーの一覧はデータ全体をスキャンしないと不定なので
予めキーの一覧を取得するという処理が必要になります。

値が空のCellをポインタ型で表現するとnilで表現できます。

実装の例を挙げてみます。
https://play.golang.org/p/lao9Q2qP4Ot

go

1package main 2 3import ( 4 "fmt" 5 "strings" 6) 7 8type Cell struct { 9 key string 10 value int 11} 12 13type Row struct { 14 cells []*Cell 15} 16 17func keys(hoge []Row) []string { 18 uniq := map[string]bool{} 19 res := []string{} 20 for _, r := range hoge { 21 for _, c := range r.cells { 22 if c == nil { 23 continue 24 } 25 if !uniq[c.key] { 26 uniq[c.key] = true 27 res = append(res, c.key) 28 } 29 } 30 } 31 return res 32} 33 34func main() { 35 row1 := Row{ 36 []*Cell{ 37 &Cell{"a", 1}, 38 &Cell{"b", 2}, 39 &Cell{"c", 3}, 40 nil, 41 }, 42 } 43 44 row2 := Row{ 45 []*Cell{ 46 &Cell{"a", 1}, 47 &Cell{"b", 2}, 48 &Cell{"c", 3}, 49 &Cell{"d", 4}, 50 }, 51 } 52 53 row3 := Row{ 54 []*Cell{ 55 &Cell{"a", 1}, 56 nil, 57 &Cell{"c", 3}, 58 &Cell{"d", 4}, 59 }, 60 } 61 62 hoge := []Row{row1, row2, row3} 63 64 fmt.Println(strings.Join(keys(hoge), ",")) 65 for _, r := range hoge { 66 line := []string{} 67 for _, c := range r.cells { 68 if c == nil { 69 line = append(line, "") 70 } else { 71 line = append(line, fmt.Sprintf("%d", c.value)) 72 } 73 } 74 fmt.Println(strings.Join(line, ",")) 75 } 76}

もちろんこの例だといくつか問題が残っています。

  • Cellのキーが実際の表示列かどうかが無視される。
  • nilを埋めるのが面倒かつ正確さが求められる。

これらの解決にはcellsをスライスではなくmapで持つと良いでしょう。

投稿2019/11/12 01:31

編集2019/11/14 03:43
nobonobo

総合スコア3367

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hizuh

2019/11/12 16:09

回答ありがとうございます。 質問の説明が不足しており、申し訳ありません。 期待しているのは「"a","","c","d"」という結果ではなく、 次のような結果を期待しています。 a,b,c,d, 1,2,3,, 1,2,3,4, 1,,3,4, row1, row2, row3 にどのような値の Cell があった場合でも、 上記のように列を揃えて出力するコードを作りたいのです。
nobonobo

2019/11/12 16:38 編集

a,b,c...はキーの事でしたか。 私の回答は値の並びについて述べているのでa,b,cは数値に読み替えてください。
nobonobo

2019/11/12 16:43

スライスというデータ構造を使う限り省略は許されないという事です。例えば3x3のデータ構造をあらかじめ作っておき、必要なところをに値埋めるという事です。 キーと値のペアをデータとして持ちたいのならmapを使うべきでしょう。
hizuh

2019/11/19 03:14 編集

丁寧な回答ありがとうございました。 丁寧に説明していただいたおかげで、どのように作っていけばよいか分かりました。 mapの使用を検討したいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問