質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

3回答

2646閲覧

固定の配列に動的に作成した配列を追加したい

cutedog

総合スコア177

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2019/01/31 08:47

編集2019/02/01 04:15

こんにちは。

下記の変数名Objの「★固定の配列」に、ループ処理にて「★動的に追加したい値」の内容に
動的Aと動的Bの箇所を動的に変化させた文字列をセットし
変数名Objの「★固定の配列」に追加していきたい。
結果として「★結果」のようにしたいのですが
どのようにすれば良いでしょうか?
ご教授宜しくお願い致します。

C#

1★固定の配列 2 Object[,] Obj = { 3 { "ID", "UniqId", 70, false, VerticalAlign.Middle, HorizontalAlign.Center, "LABEL_CHAR" }, 4 { "職員名", "ShokuinName", 320, true, VerticalAlign.Middle, HorizontalAlign.Left, "LABEL_CHAR" }, 5 }; 6 7**************************************************************************************************************** 8★動的に追加したい値 9 ※動的Aと動的Bはループ処理により動的に命名する 10{ 動的A, 動的B, 80, true, VerticalAlign.Middle, HorizontalAlign.Center, "MONEY" }, 11**************************************************************************************************************** 12 13★結果 14 15 Object[,] Obj = { 16 { "ID", "UniqId", 70, false, VerticalAlign.Middle, HorizontalAlign.Center, "LABEL_CHAR" }, 17 { "職員名", "ShokuinName", 320, true, VerticalAlign.Middle, HorizontalAlign.Left, "LABEL_CHAR" }, 18 { "ほげほげ1", "Hogehoge1", 80, true, VerticalAlign.Middle, HorizontalAlign.Center, "MONEY" }, 19 { "ほげほげ2", "Hogehoge2", 80, true, VerticalAlign.Middle, HorizontalAlign.Center, "MONEY" }, 20 { "ほげほげ3", "Hogehoge3", 80, true, VerticalAlign.Middle, HorizontalAlign.Center, "MONEY" }, 21 { "ほげほげ4", "Hogehoge4", 80, true, VerticalAlign.Middle, HorizontalAlign.Center, "MONEY" }, 22 23

List形式からObject[,]への変換までを書いてみました。
なんとかできました。ありがとうございました。

C#

1 var objList = new List<List<object>>(); 2 objList.Add(new List<object>() { "UniqId", "UniqId", 70, false, 11111, 22222, "LABEL_CHAR" }); 3 objList.Add(new List<object>() { "職員名", "ShokuinName", 320, true, 11111, 22222, "LABEL_CHAR" }); 4 objList.Add(new List<object>() { "科目コード", "AAA", 80, true, 11111, 22222, "MONEY" }); 5 6 for (var i = 0; i < 10; i++) 7 { 8 9 objList.Add(new List<object>() { "ほげほげ" + i, "Hogehoge" + i, 80, true, 11111, 22222, "MONEY" }); 10 11 } 12 13 //これだとObject[][]になってしまう 14 //var parsedList = objList 15 // .Select(val => val 16 // .Select(val2 => val2).ToArray() 17 // ).ToArray(); 18 19 var rowCount = objList.Count; 20 var colCount = 7; 21 22 var r = new Object[objList.Count, 7]; 23 24 for (int y = 0; y < rowCount; y++) 25 { 26 var src = objList[y]; 27 for (int x = 0; x < colCount; x++) 28 { 29 r[y, x] = objList[x]; 30 } 31 }

実装してみました。
うまくいきました。

C#

1 2using System; 3using System.Collections.Generic; 4using System.Linq; 5using System.Text; 6using System.Threading.Tasks; 7 8namespace WindowsFormsApplication1 9{ 10 public class Poco 11 { 12 public string Name; 13 public string Id; 14 public int Width; 15 public bool IsValid; 16 public int Valign; 17 public int Halign; 18 public string Label; 19 public Poco(string name, string id, int width, bool isvalid, int valign, int halign, string label) 20 { 21 Name = name; Id = id; Width = width; IsValid = isvalid; Valign = valign; Halign = halign; Label = label; 22 } 23 24 25 public static IList<Poco> ToList(object[,] hatchpotch) 26 { 27 var innerLen = 7; 28 var outerLen = hatchpotch.Length / innerLen; 29 return Enumerable.Range(0, outerLen).Select(i => new Poco((string)hatchpotch[i, 0], (string)hatchpotch[i, 1], (int)hatchpotch[i, 2], (bool)hatchpotch[i, 3], (int)hatchpotch[i, 4], (int)hatchpotch[i, 5], (string)hatchpotch[i, 6])).ToList(); 30 } 31 32 public static object[,] ToRect(IList<Poco> data) //理解しやすくするためList<Poco>としてます。実用では副作用に注意しましょう 33 { 34 var ret = new object[data.Count(), 7]; 35 for (var i = 0; i < data.Count(); i++) 36 { 37 ret[i, 0] = (object)data[i].Name; 38 ret[i, 1] = (object)data[i].Id; 39 ret[i, 2] = (object)data[i].Width; 40 ret[i, 3] = (object)data[i].IsValid; 41 ret[i, 4] = (object)data[i].Valign; 42 ret[i, 5] = (object)data[i].Halign; 43 ret[i, 6] = (object)data[i].Label; 44 } 45 return ret; 46 } 47 48 49 } 50 51} 52 53 54 55//実行部 56sub main() 57{ 58 Object[,] Obj = { 59 { "UniqId", "UniqId", 70, false, 11111, 22222, "LABEL_CHAR" }, 60 { "職員名", "ShokuinName", 320, true, 11111, 22222, "LABEL_CHAR" }, 61 { "科目コード", "AAA", 80, true, 11111, 22222, "MONEY" }, 62 }; 63 64 IList<Poco> PocoList = Poco.ToList(Obj); 65 66 67 for (var i = 0; i < 10; i++) 68 { 69 Poco _Poco = new Poco("ほげほげ" + i, "Hogehoge" + i, 80, true, 11111, 22222, "MONEY"); 70 PocoList.Add(_Poco); 71 } 72 73 74 Object[,] Obj2 = Poco.ToRect(PocoList); 75} 76

元々コボラーの独学なので
低レベルなコーディングでお目汚しですが
毎回、案件ごとにSPREAD定義を一から書くのが億劫だったので
SPREAD for WinFormsもASP.NETでも同じように
以下のような関数に[,]を食わせて定義してます。

C#

1 /// <summary> 2 /// スプレッドシート設定 3 /// </summary> 4 /// <param name="sheet"></param> 5 /// <param name="hd"></param> 6 /// <param name="FrozenColumnCount"></param> 7 /// <param name="FrozenRowCount"></param> 8 /// <param name="rowHeader"></param> 9 /// <param name="columnHeader"></param> 10 /// <param name="allowGroup"></param> 11 /// <param name="columnHeaderSet"></param> 12 /// <param name="AlternatingSw"></param> 13 public void InitSpreadStyles(FarPoint.Web.Spread.SheetView sheet, 14 Object[,] hd = null, 15 int FrozenColumnCount = 0, 16 int FrozenRowCount = 0, 17 Boolean rowHeader = true, 18 Boolean columnHeader = true, 19 Boolean allowGroup = false, 20 Boolean columnHeaderSet = true, 21 Boolean AlternatingSw = true) 22 { 23 24 FarPoint.Web.Spread.Inset mg = new FarPoint.Web.Spread.Inset(3, 0, 3, 0); 25 26 // 余白の設定をシートに適用 27 sheet.DefaultStyle.Margin = mg; 28 29 sheet.GridLines = GridLines.Both; 30 31 sheet.DefaultStyle.Border.BorderColor = Color.LightBlue; 32 sheet.DefaultStyle.Border.BorderSize = 1; 33 sheet.DefaultStyle.Border.BorderStyle = BorderStyle.Solid; 34 35 //選択行の色 36 sheet.SelectionBackColor = System.Drawing.Color.Silver; 37 38 // 縦方向の揃え位置を中央に設定 39 sheet.DefaultStyle.VerticalAlign = VerticalAlign.Middle; 40 41 //バインドしたデータでのカラム作成を抑止する 42 sheet.AutoGenerateColumns = false; 43 44 //カラム移動を可能にする 45 sheet.AllowColumnMove = false; 46 47 if (hd != null) 48 { 49 //カラムを作成 50 sheet.ColumnCount = hd.GetLength(0); 51 for (int x = 0; x <= hd.GetLength(0) - 1; ++x) 52 { 53 if (columnHeaderSet) 54 { 55 // カラムヘッダを設定します。 56 sheet.ColumnHeader.Cells[0, x].Text = (String)hd[x, 0]; 57 } 58 59 sheet.Columns[x].DataField = (String)hd[x, 1]; 60 61 sheet.Columns[x].Width = (int)hd[x, 2]; 62 63 sheet.Columns[x].Visible = (Boolean)hd[x, 3]; 64 65 sheet.Columns[x].VerticalAlign = (VerticalAlign)hd[x, 4]; 66 67 sheet.Columns[x].HorizontalAlign = (HorizontalAlign)hd[x, 5]; 68 69 sheet.Columns[x].Font.Name = "Meiryo UI"; 70 71 //セルタイプをセット 72 String cellType = (String)hd[x, 6]; 73 74 if (String.IsNullOrEmpty(cellType)) 75 { 76 sheet.Columns[x].CanFocus = false; 77 sheet.Columns[x].Locked = true; 78 } 79 80 if ("LABEL_NUM".Equals(cellType)) 81 { 82 LabelCellType celltype = new LabelCellType(); 83 celltype.AllowWrap = false; 84 sheet.Columns[x].CellType = celltype; 85 } 868788 ・いろんなcelltypeの設定を定義してます 89909192 93 } 94 } 95 96 // グルーピング設定 97 sheet.AllowGroup = allowGroup; 98 sheet.GroupBarVisible = allowGroup; 99 100 if (AlternatingSw) 101 { 102 // 1行おきにスタイルを設定します 103 sheet.AlternatingRows.Count = 2; 104 System.Drawing.Color fc = System.Drawing.Color.FromName("OldLace"); 105 sheet.AlternatingRows[1].BackColor = fc; 106 } 107 108 // 行ヘッダ表示制御 109 sheet.RowHeader.Visible = rowHeader; 110 // 列ヘッダ表示制御 111 sheet.ColumnHeader.Visible = columnHeader; 112 // 列の固定 113 sheet.FrozenColumnCount = FrozenColumnCount; 114 // 行の固定 115 sheet.FrozenRowCount = FrozenRowCount; 116 117 118 }

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

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

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

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

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

papinianus

2019/02/01 03:00 編集

興味本位で申し訳ないのですが、SPREAD for WinFormsって[,]で操作するものなのですか? SPREADだから、列が変動できる、のだと思いますが。
cutedog

2019/02/01 04:19 編集

質問欄に食わせる関数を追記しました。 [,]では操作しません。関数用です。 SPREAD for WinFormsもASP.NETでも同じように 追記した関数に[,]を食わせて定義してます。 objList.Add(new List<object>() { "UniqId", "UniqId", 70, false, 11111, 22222, "LABEL_CHAR" });が1つの列に相当します。
guest

回答3

0

配列でやりたいということですが、List<T> を使うべきという回答です。

理由 1
配列のサイズは固定されていてループで動的に拡張できません。
Array.Resize() という配列の大きさを拡張するメソッドは確かにありますが、その内部では新しい配列を用意して既存の中身をコピーしています。
10 回拡張した場合は、同じものを 10 回コピーすることになります。

理由 2
それでも配列を拡張する場合には、一つコピーするごとに拡張するのではなく、あらかじめ大きな配列を用意し、それがいっぱいになるまではそれを使うことでパフォーマンスを上げることができます。
しかし、これは自分でやらなくてもすでに標準ライブラリで実装されています。
それが List<T> です。

List<T> のソース

これを見ると、Capacity というプロパティの大きさの配列を用意していることがわかります。

理由 3
List<T> から配列へのコピーは簡単です。
ループ中では List<T> を使い、最終的に配列が必要になった時点でコピーすることができます。

投稿2019/01/31 09:40

Zuishin

総合スコア28660

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

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

cutedog

2019/02/01 02:14

ご提案ありがとうございます。 質問欄にLIST<T>をつかうやり方を追記してみましたが あってますか? ただ、最終的にListにしたのはいいけど 配列のObject[,] Obj にコピーするにはどうしたらいいのでしょうか? Object[,] Obj = objList.ToArray();って書いてもダメみたいです。
Zuishin

2019/02/01 02:21

ざっと見ただけですが、やり方は合っています。 LINQ で二次元配列を一発で作る方法は無いので、List.Count を見て配列を用意して for でセットするのが良いと思います。 また、二次元配列でなくジャグ配列でも良いなら Object[][] Obj = objList.ToArray() でできますが、二次元配列を使う必要はありますか?
papinianus

2019/02/01 02:32

私のほうのコメントに既存コードが四角配列でできあがっているとのこと。
Zuishin

2019/02/01 02:37

そうなんですが、たとえばファイルからの読み込みなど最初に配列の大きさがわかっていないものを動的に作る場合は一度リストを経由するのが良いと思ってこの提案をしました。
cutedog

2019/02/01 02:52

この配列は、SPREADを使用する際の定義情報を書いているので、Zuishinさんのお考えのような行列が動的に変わる仕様を想定していないです。今回動的になるのは行のみの想定です。 皆さまの提案内容を見てList形式をつかってOject[,]への変換を作ってのを 質問欄に追記しました。
papinianus

2019/02/01 03:01

> 配列の大きさがわかっていない 列が固定であっても、行が変動するは、配列の縦方向の大きさが分かっていない、ではないでしょうか。
guest

0

ベストアンサー

四角配列じゃなきゃだめですかね?

四角配列つかったことないんですが、4つ増やすとして

csharp

1var Obj = //もとのやつ 2var curLen = Obj.length / 7 3var newLen = newLen + 4; 4var newObj = new object[newLen,7](); 5for(var i = 0; i < curLen; i++) 6{ 7 for(var j = 0; j < 7; j++) 8 { 9 newObj[i,j] = Obj[i,j]; 10 } 11} 12for(var i = curLen; i < newLen; i++) 13{ 14 for(var j = 0; j < 7; j++) 15 { 16 switch(j) 17 { 18 case 0: //これを7個定義する 19 newObj[i,j] = "ほげほげ1"; 20 break; 21 } 22 } 23}

とかじゃないでしょうか?


ちなみにObjがobject[][]だったら

csharp

1var newObjs = Obj.Concat(Enumerable.Range(1,4).Select(i => new object[] {$"ほげほげ{i}", $"Hogehoge{i}", 80, true, VerticalAlign.Middle, HorizontalAlign.Center, "MONEY" });

csharp

1class Poco 2{ 3 public string Name; 4 public string Id; 5 public int Width; 6 public bool IsValid; 7 public int Valign; 8 public int Halign; 9 public sring Label; 10 public Poco(string name, string id, int width, bool isvalid; int valign, int halign, string label) 11 { 12 Name = name; Id = id; Width = width; IsValid = isvalid; Valign = valign; Halign = halign; Label = label; 13 } 14} 15public List<Poco> ToList(object[,] hatchpotch) 16{ 17 var inner = 7; 18 var outerLen = hatchpotch.Length / innerLen; 19 return Enumerable.Range(0, outerLen).Select(i=>new Poco((string)hatchpotch[i,0],(string)hatchpotch[i,1],(int)hatchpotch[i,2],(bool)hatchpotch[i,3],(int)hatchpotch[i,4],(int)hatchpotch[i,5],(string)hatchpotch[i,6])).ToList(); 20} 21public object[,] ToRect(List<Poco> data) //理解しやすくするためList<Poco>としてます。実用では副作用に注意しましょう 22{ 23 var ret = new object[data.Count(), 7]; 24 for(var i = 0; i < data.Count(); i++) 25 { 26 ret[i,0] = (object)data[i].Name; 27 ret[i,1] = (object)data[i].Id; 28 ret[i,2] = (object)data[i].Width; 29 ret[i,3] = (object)data[i].IsValid; 30 ret[i,4] = (object)data[i].Valign; 31 ret[i,5] = (object)data[i].Halign; 32 ret[i,6] = (object)data[i].Label; 33 } 34 return ret; 35}

投稿2019/01/31 09:16

編集2019/02/01 03:15
papinianus

総合スコア12705

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

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

papinianus

2019/01/31 09:17

四角配列ってlengthとってもforeachしてもシーケンシャルにしか出てこないしLinqとの相性も最悪なんで、私は基本避けてます。 1列のサイズが固定できるメリットに対して、ハンドリングがつらすぎる。
cutedog

2019/02/01 02:16

ご提案ありがとうございます。 Object[,]型を利用したロジックがすでに実装されているので このObject[,]型でないとちょっと困るんですよね。
papinianus

2019/02/01 02:29 編集

提案以前に水平線より上には、四角配列でやりたいことをコードそのままで書いてます。 原理的にはforでつめていくしかなくて、こういう無駄に面倒なことが必要なんです。 > Object[,]型を利用したロジックがすでに実装されているので だいたい察していましたが、誠に残念ですとしか言いようがないです。 今回のはそもそもネストした配列の型ではなく、きちんとSomeInfoみたいなstruct/classを作って、SomeInfo[]とすべきでした。
cutedog

2019/02/01 02:49

すいません。なにぶんC#を習いたての頃に書いたコードでして、特に問題なかったのでそのまま使用していまして。。。今にして思えばもっと書きようがあったように思います。
papinianus

2019/02/01 02:54

今からでもいくらでも取り返せます。 リストにするのと、リストに戻すのユーティリティを書いたのでご参考に(型や名前は推測です)。 もう速度の追求とかメモリの追求とかはあきらめていただいて。 一旦、前のデータ(Obj)をToListでList<Poco>にして、そこに追加したいやつをどんどん動的に追加 `list.Add(new Poco("動的1","動的2", 1, true,2,3,"label")`していって、できたものをToRectで戻せば他のメソッドに食わせられるでしょう。
papinianus

2019/02/01 02:58

どっちにコメントするか迷いましたが、こちらで。 追記した方法は意味的には正しいと思いますし、私が書いたのも実体としては同じだと思いますが、関数に抽象化したほうがいいと思います(object[,]で扱いにくい問題がでてきたらまた同じようなことをすることになるから) あと、型安全の世界に戻ってください。
cutedog

2019/02/01 03:14

ありがとうございます。すごいー。の一言です。 こちらで、貼り付けしたのですがEnumerableで以下のようなエラーになります。 これって何かこちらの環境が悪いんでしょうか? IEnumerable<out T>を実装するオブジェクトをクエリするための一連のstaticメソッドを提供します。 実行不可能なメンバー'Enumerable'をメソッドのように使用できません。
papinianus

2019/02/01 03:16

Enumerab.Range(0、でした「.Range」が抜けてました。回答を修正してます(VS使わないといけないですね)
cutedog

2019/02/01 03:21

Enumerable.Rangeですかね? return Enumerable.Range(0, outerLen).Select(i => new Poco((string)hatchpotch[i, 0], (string)hatchpotch[i, 1], (int)hatchpotch[i, 2], (bool)hatchpotch[i, 3], (int)hatchpotch[i, 4], (int)hatchpotch[i, 5], (string)hatchpotch[i, 6])).ToList();
cutedog

2019/02/01 03:22

あっと、素早い回答でありがとうございます。更新してなかったのでわかりませんでした。
cutedog

2019/02/01 03:25

まだ少し文法エラーがありましたが補正できました。。 VS使わずこれが書けるのがすごいです。
papinianus

2019/02/01 03:25

> まだ少し文法エラーがありましたが おはずかしい限り
cutedog

2019/02/01 03:45

うまく実装できました。 ありがとうございました。 ついでに教えてほしいのですが コメントで「理解しやすくするためList<Poco>としてます。実用では副作用に注意しましょう」 と書かれていますが、副作用とはどういったものなのかが想像がつかないのですが・・・
papinianus

2019/02/01 03:55

ToRectは本来、かたちをかえるだけで、職員1を「しょくいん1」にすることを想定していません(後から見たときにそういう想像をしません) しかし、List<T>で渡すと、中身を書きかえることが(ミスかもしれませんし、便利だからついでにやっちゃおうかもしれません)できてしまいます。 この辺、コメントで書けるレベルじゃないので「https://qiita.com/lobin-z0x50/items/248db6d0629c7abe47dd」とかを参考にしてください。
guest

0

2次元配列の場合、大きい配列を再定義して、中身をコピーする形になるかと思います。
object[][]のようなジャグ配列ですとArray.Resizeを使用することができます。
また、List<T>を使用したほうがすっきりするような気もします。

投稿2019/01/31 09:13

YAmaGNZ

総合スコア10251

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

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

cutedog

2019/02/01 02:19

ご提案ありがとうございます。 そうですね。Zuishinさんの提案してくれている List<T>がいいようにおもったので、 質問欄に追記してみました。 けどObject[,]型にコピーする方法がわからない・・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問